2009-05-18 10 views
9

Wenn ich die folgende SQL-AbfrageSQL Reihenfolge der Operationen

SELECT * 
FROM A 
LEFT JOIN B 
ON A.foo=B.foo 
WHERE A.date = "Yesterday" 

Ist die WHERE Anweisung vor fahren werden ausgewertet oder nach dem JOIN?

Wenn nach, was wäre eine bessere Möglichkeit, diese Anweisung zu schreiben, so dass nur Zeilen in A von "Yesterday" mit B verbunden werden?

+0

'was eine bessere Möglichkeit wäre, diese Erklärung zu schreiben, so dass nur die Zeilen in A von "Yesterday" werden mit B verbunden. (späte Antwort) -> 'INNER JOIN' –

Antwort

8

Es hängt von der Datenbank ab.

Führen Sie auf SQL Server: SET SHOWPLAN_ALL ON dann die Abfrage ausführen, erhalten Sie eine Vorstellung davon, was passiert, wenn es ausgeführt wird.

1

Hängt von Indizes und Statistiken ab.

Sie sollten den Ausführungspfad der Abfrage anzeigen, um zu bestimmen, wo (falls vorhanden) Optimierungen angewendet werden sollen.

5

Semantisch: Nach dem JOIN. Aber in diesem Fall gibt es keinen Unterschied im Timing, da es sich auf der LINKEN Seite des JOIN befindet.

Wie Sie bereits haben, "nur Zeilen in A von" Gestern "sind mit B verbunden".

Der Optimierer kann die Reihenfolge seiner Operationen abhängig von den Äquivalenzen in der relationalen Algebra reorganisieren.

Das gibt nur A.date = "Yesterday" und verbindet B, wo es ein Spiel auf foo finden:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
WHERE A.date="Yesterday" 

Dieser gibt alle A unabhängig von irgendwelchen Kriterien und verbindet B, wo A.date =“ Gestern "UND es findet eine Übereinstimmung auf foo:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
    AND A.date="Yesterday" 
+0

Nur zu verstehen, sagen Sie, dass das Setzen der Kriterien in die WHERE-Klausel aus Performance-Sicht besser ist, als in die JOIN-Klausel zu schreiben? – NotMe

+0

Es macht keinen Unterschied zu der Leistung eines INNER JOIN und das ist der Grund, warum der Optimierer mehr Möglichkeiten hat, Dinge auf INNER JOINs zu verschieben. Bei einem OUTER JOIN (LINKS oder RECHTS) wirkt sich dies auf die Semantik der Deklaration aus, so dass die Leistung normalerweise nicht das Problem ist. –

7

Ihre Idee von" Auswertung "ist nicht korrekt, da SQL eine deklarative Sprache ist.

BTW Sie können den Abfrageausführungsplan sehen. In MySQL Präfix Ihre Abfrage mit dem Schlüsselwort describe, um den Ausführungsplan zu sehen.

2

Die Reihenfolge der Vorgänge zum Erfüllen einer Abfrage wird bestimmt, warum die Laune des Abfrage-Optimierers der bestimmten Datenbank. Ein Abfrageoptimierer versucht, einen guten "Abfrageplan" (eine Menge von Operationen) auf der Basis dessen zu erstellen, was er aus der Abfrage und den vorhandenen Statistiken über die Datenbank erhalten kann (was die Kardinalität von Tabellen und bestimmten Datenverteilungen beinhalten könnte). .

In Ihrem Fall kann die Antwort davon ab, ob Sie auf A.date einen Sekundärindex haben

Abfrageoptimierung ein ziemlich reiches Thema. Die Dokumentation für die von Ihnen verwendete Datenbank wird viel mehr zu sagen haben.

1

in SQL Server:

Als allgemeine Faustregel sind JOIN-Klauseln vor WHERE-Klauseln ausgewertet.

Bei komplexen Joins, die Notwendigkeit Filter in dem Teil verbinden, ich schreibe sie zusammen mit meiner verbinden

SELECT * 
FROM A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
    And A.Date = 'Yesterday' 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3 
+0

Dies hat nicht die gleiche Bedeutung, wenn Sie es innerhalb des LINKEN JOIN verwenden. Wenn die Kriterien im LEFT JOIN nicht erfüllt sind, werden die LEFT-Zeilen weiterhin zurückgegeben, und alle Spalten von RIGHT sind NULL. –

+0

Ich stehe auf dem angegebenen Beispiel korrigiert. Ich habe versucht, den Punkt, wo ein Teil einer Klausel zusammen mit dem passenden Join zu setzen. Ich habe die Aussage korrigiert. –

+0

:) Ich stehe recorrected .. Ich kann die Aussage nicht korrigieren. –

0
SELECT * 
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3