Gibt es einen Unterschied (Leistung, Best Practice usw.) zwischen dem Einfügen einer Bedingung in die JOIN-Klausel und der WHERE-Klausel?
Beispielsweise...
-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'
-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'
Welches bevorzugen Sie (und vielleicht warum)?
sql
performance
Steve Dignan
quelle
quelle
FROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
Antworten:
Die relationale Algebra ermöglicht die Austauschbarkeit der Prädikate in der
WHERE
Klausel und derINNER JOIN
, sodass selbst beiINNER JOIN
Abfragen mitWHERE
Klauseln die Prädikate vom Optimierer neu angeordnet werden können, sodass sie möglicherweise bereits während desJOIN
Prozesses ausgeschlossen werden.Ich empfehle Ihnen, die Abfragen so gut wie möglich zu schreiben.
Manchmal beinhaltet dies das
INNER JOIN
relativ "unvollständige" und das Einfügen einiger Kriterien inWHERE
die Liste, um die Liste der Filterkriterien einfacher zu pflegen.Zum Beispiel anstelle von:
Schreiben:
Aber es kommt natürlich darauf an.
quelle
Bei inneren Verknüpfungen habe ich keinen wirklichen Unterschied festgestellt (aber wie bei jeder Leistungsoptimierung müssen Sie unter Ihren Bedingungen eine Überprüfung Ihrer Datenbank durchführen).
Wo Sie die Bedingung setzen, macht jedoch einen großen Unterschied, ob Sie linke oder rechte Verknüpfungen verwenden. Betrachten Sie zum Beispiel diese beiden Abfragen:
Mit dem ersten werden nur die Datensätze angezeigt, deren Bestellung später als am 15. Mai 2009 datiert wurde. Dadurch wird der linke Join in einen inneren Join konvertiert. Die zweite gibt diese Aufzeichnungen sowie alle Kunden ohne Bestellungen. Die Ergebnismenge ist sehr unterschiedlich, je nachdem, wo Sie die Bedingung setzen. (Wählen Sie *, wenn Sie dies beispielsweise nur zu Zwecken verwenden möchten, natürlich nicht im Produktionscode.) Die Ausnahme ist, wenn Sie nur die Datensätze in einer Tabelle anzeigen möchten, nicht jedoch in der anderen. Dann verwenden Sie die where-Klausel für die Bedingung, nicht den Join.
quelle
A left join B
Ist jede Zeile von A mit jeder übereinstimmenden Zeile von B verbunden ? Wenn B keine übereinstimmende Zeile hat, haben die A-Spalten einen Wert, aber jede Spalte von B in dieser Zeile wird als NULL-Wert angezeigt. Wenn Sie geschrieben haben, habenwhere B.somecolumn = ‘somevalue’
Sie eine NULL (B.somecolumn), die mit 'somevalue' verglichen wird. Alles, was mit NULL verglichen wird, ist falsch, sodass alle Ihre Zeilen, in denen es keine übereinstimmende B-Zeile für die A-Zeile gibt, eliminiert werden und die Ergebnisse, die Sie erhalten, die gleichen sind, die ein INNER JOIN liefern würde, daher ist der äußere Join ein innerer gewordenfunds
Inner Join-Interessenten auf (spects.id = Funds.lead_id und Prospects.is_manual = 'Nein') und SELECT Funds.id, Prospects.id FROMfunds
Left Schließen Sie sich potenziellen Kunden an unter (spects.id = funds.lead_id), wobeispects.is_manual = 'no'Die meisten RDBMS-Produkte optimieren beide Abfragen identisch. In "SQL Performance Tuning" von Peter Gulutzan und Trudy Pelzer haben sie mehrere RDBMS-Marken getestet und keinen Leistungsunterschied festgestellt.
Ich bevorzuge es, Join-Bedingungen von Abfrageeinschränkungsbedingungen getrennt zu halten.
Wenn Sie
OUTER JOIN
manchmal verwenden, müssen Bedingungen in die Join-Klausel eingefügt werden.quelle
WHERE wird nach dem JOIN gefiltert.
Filtern Sie nach JOIN, um zu verhindern, dass während des JOIN-Prozesses Zeilen hinzugefügt werden.
quelle
ON
Ich bevorzuge JOIN, um vollständige Tabellen / Ansichten zu verbinden und dann das WHERE zu verwenden, um das Prädikat der resultierenden Menge einzuführen.
Es fühlt sich syntaktisch sauberer an.
quelle
Ich sehe normalerweise Leistungssteigerungen beim Filtern nach dem Join. Insbesondere, wenn Sie indizierte Spalten für beide Tabellen verknüpfen können. Sie sollten in der Lage sein, logische Lesevorgänge bei den meisten Abfragen zu reduzieren, was in einer Umgebung mit hohem Volumen ein viel besserer Leistungsindikator als die Ausführungszeit ist.
Ich bin immer leicht amüsiert, wenn jemand sein SQL-Benchmarking zeigt und beide Versionen eines Sproc 50.000 Mal um Mitternacht auf dem Dev-Server ausgeführt und die Durchschnittszeiten verglichen hat.
quelle
Das Einfügen der Bedingung in den Join scheint mir "semantisch falsch" zu sein, da JOINs nicht "dafür" sind. Das ist aber sehr qualitativ.
Zusätzliches Problem: Wenn Sie sich entscheiden, von einem inneren Join zu einem richtigen Join zu wechseln, kann die Bedingung innerhalb des JOIN zu unerwarteten Ergebnissen führen.
quelle
Joins sind meiner Meinung nach schneller, wenn Sie einen größeren Tisch haben. Es ist wirklich kein so großer Unterschied, besonders wenn Sie es mit einem eher kleineren Tisch zu tun haben. Als ich zum ersten Mal von Joins erfuhr, wurde mir gesagt, dass Bedingungen in Joins genau wie Bedingungen für where-Klauseln sind und dass ich sie austauschbar verwenden könnte, wenn die where-Klausel spezifisch wäre, für welche Tabelle die Bedingung ausgeführt werden soll.
quelle
Es ist besser, die Bedingung im Join hinzuzufügen. Leistung ist wichtiger als Lesbarkeit. Für große Datenmengen ist es wichtig.
quelle