2009-07-07 16 views
6

Ich sollte das wahrscheinlich schon wissen, aber was, wenn überhaupt, ist der Unterschied zwischen den beiden folgenden Aussagen?SQL - Unterschied zwischen diesen Joins?

Die verschachtelte beitreten:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

Die traditionellere join:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
+0

Geben sie das gleiche Ergebnis, wenn Sie sie ausführen? –

+0

+1 für mich zu gehen "Hm ..." – Tomalak

+0

Es ist eine viel leichter zu verstehen, die zweite als die erste - auch wenn Sie (Parens) um die LOJ in der ersten setzen. Ich freue mich darauf, eine gute Antwort zu diesem Thema abzugeben. –

Antwort

5

Nun setzen können, ist es die Reihenfolge der Operationen ..

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

neu geschrieben werden kann als:

SELECT 
    t1.* 
FROM 
     table1 t1              -- inner join t1 
    INNER JOIN 
     (table2 t2 LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID) -- with this 
    ON t2.table2_ID = t1.table1_ID          -- on this condition 

Also im Grunde der erste Straße links Sie t2 mit t3 JOIN, auf der Join-Bedingung basiert: table3_ID = table2_ID, dann JOIN Sie INNER t1 mit t2 auf table2_ID = table1_ID.

In Ihrem zweiten Beispiel zuerst INNER JOIN t1 mit t2, und dann LEFT JOIN der resultierende innere Join mit Tabelle t3 auf der Bedingung table2_ID = table1_ID.

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID   

werden könnte neu geschrieben als:

SELECT 
    t1.* 
FROM 
     (table1 t1 INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID) -- first inner join 
    LEFT JOIN               -- then left join 
     table3 t3 ON t3.table3_ID = t2.table2_ID      -- the result with this 

EDIT

Ich entschuldige mich. Meine erste Bemerkung war falsch. Die zwei Abfragen führen zu denselben Ergebnissen, aber es kann zu Leistungsunterschieden kommen, da die erste Abfrage in manchen Fällen langsamer ausgeführt werden kann als die zweite Abfrage (wenn Tabelle 1 nur eine Teilmenge der Elemente in Tabelle 2 enthält), wie dies bei LEFT JOIN der Fall ist zuerst ausgeführt werden - und dann nur mit table1 geschnitten werden. Im Gegensatz zu der zweiten Abfrage, die es dem Abfrageoptimierer ermöglicht, seine Aufgabe zu erledigen.

+1

Offensichtlich ist die Reihenfolge der Operationen anders, aber gibt es einen tatsächlichen Unterschied (Leistung, Ergebnisse, irgendetwas)? –

+1

Geben Sie ein Beispiel für Daten an, bei denen die Abfragen unterschiedliche Ergebnisse liefern. Ich konnte keine generieren. –

+0

Ok, danke für die Gedanken an diese Jungs. Es ist ziemlich genau so, wie ich damals gedacht habe. Die Ergebnisse werden die gleichen sein, aber die Abfragen können sich unterschiedlich verhalten. Ich denke für die Benutzerfreundlichkeit, werde ich die alte (geschachtelte) Abfrage ändern, um die traditionellere Syntax zu verwenden. – TehOne

4

Für Ihr spezielles Beispiel, ich glaube nicht, dass es in den Abfrageplänen ein Unterschied sein sollte generiert, aber es gibt definitiv einen Unterschied in der Lesbarkeit. Ihr zweites Beispiel ist VIEL einfacher zu folgen.

Wenn Sie die Join-Typen in diesem Beispiel umkehren, können Sie sehr unterschiedliche Ergebnisse erzielen.

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 

-- may not produce the same results as... 

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

Basierend auf der Tatsache, dass Reihenfolge des Joins ist von Bedeutung in vielen Fällen - sorgfältige Überlegung sollte in gehen, wie Sie schreiben Ihre Join-Syntax. Wenn Sie, dass das zweite Beispiel finden ist, was Sie wirklich zu erreichen versucht, würde ich prüfen, die Abfrage umschreiben, so dass Sie mehr Wert auf die Reihenfolge der Joins ...

SELECT t1.* 
FROM table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
     RIGHT JOIN table1 t1 ON t2.table2_ID = t1.table1_ID 
2

Der beste Weg zu sehen, was in diesen beiden Abfragen anders ist, ist der Vergleich des Abfrageplans für diese beiden Abfragen.

Es gibt keinen Unterschied in den Ergebnissätzen für diese IF Es gibt immer Zeilen in Tabelle3 für eine bestimmte Zeile in Tabelle2.

Ich versuchte es auf meiner Datenbank und der Unterschied in den Abfrageplänen war, dass 1. Für die erste Abfrage entschied der Optimierer, die Verknüpfung auf Tabelle2 und Tabelle 3 zuerst zu tun. 2.Für die zweite Abfrage hat der Optimierer ausgewählt, zuerst Tabelle1 und Tabelle2 beizutreten.

+0

Für mich waren die Ausführungspläne für meine echten Abfragen genau gleich. – TehOne

0

Sie sollten zwischen den beiden Abfragen überhaupt keinen Unterschied sehen, vorausgesetzt Ihr DBMS-Optimierer ist auf dem neuesten Stand. Dies ist jedoch selbst für große, kostspielige Plattformen keine Annahme, die ich mir vorstellen könnte. Daher wäre ich ziemlich überrascht, herauszufinden, dass die Abfragepläne (und folglich die Ausführungszeiten) variieren.