it-swarm.com.de

Bedingung innerhalb von JOIN oder WO

Gibt es einen Unterschied (Leistung, Best-Practice usw.) zwischen dem Setzen einer Bedingung in der JOIN-Klausel und der WHERE-Klausel?

Zum Beispiel...

-- 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)?

157
Steve Dignan

Die relationale Algebra ermöglicht die Austauschbarkeit der Prädikate in der WHERE-Klausel und dem INNER JOIN, sodass INNER JOIN-Abfragen mit WHERE-Klauseln die Prädikate so anordnen können, dass sie vom Optimierer umgeordnet werden, sodass sie möglicherweise bereits ausgeschlossen während des JOIN-Prozesses sind.

Ich empfehle, dass Sie die Abfragen so lesbar wie möglich schreiben.

Dies beinhaltet manchmal, den INNER JOIN relativ "unvollständig" zu machen und einige der Kriterien in die WHERE zu setzen, um die Liste der Filterkriterien einfacher pflegen zu können.

Zum Beispiel anstelle von:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Schreiben:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Aber es kommt natürlich darauf an.

129
Cade Roux

Bei Inner Joins habe ich eigentlich keinen Unterschied bemerkt (aber wie bei jeder Leistungsoptimierung müssen Sie unter Ihren Bedingungen mit Ihrer Datenbank vergleichen).

Wo Sie die Bedingung einfügen, ist jedoch ein großer Unterschied, wenn Sie Links- oder Rechtsverknüpfungen verwenden. Betrachten Sie zum Beispiel diese beiden Abfragen:

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

Beim ersten werden nur die Datensätze angezeigt, deren Auftrag später als der 15. Mai 2009 datiert wurde. Der linke Join wird also in einen inneren Join umgewandelt. Der zweite Teil enthält diese Aufzeichnungen sowie alle Kunden ohne Bestellungen. Die Ergebnismenge ist sehr unterschiedlich, je nachdem, wo Sie die Bedingung eingeben. (Wählen Sie *, wenn Sie nur zu Beispielzwecken natürlich nicht im Produktionscode verwenden sollen.) Die Ausnahme ist, wenn Sie nur die Datensätze in einer Tabelle sehen möchten, nicht jedoch die andere. Dann verwenden Sie die where-Klausel für die Bedingung, nicht den Join. 

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderID is null
101
HLGEM

Die meisten RDBMS-Produkte optimieren beide Abfragen identisch. In "SQL Performance Tuning" von Peter Gulutzan und Trudy Pelzer testeten sie mehrere Marken von RDBMS und fanden keinen Leistungsunterschied.

Ich bevorzuge es, Verknüpfungsbedingungen getrennt von Abfrageeinschränkungsbedingungen zu halten.

Wenn Sie OUTER JOIN verwenden, müssen manchmal Bedingungen in die Join-Klausel eingefügt werden.

23
Bill Karwin

WHERE wird filtern, nachdem der JOIN aufgetreten ist.

Filtern Sie nach dem JOIN, um zu verhindern, dass Zeilen während des JOIN-Prozesses hinzugefügt werden.

11
TheTXI

Ich ziehe es vor, mit JOIN vollständige Tabellen/Views zu verknüpfen und dann WHERE zu verwenden, um das Prädikat der Ergebnismenge einzuführen.

Es fühlt sich syntaktisch sauberer an.

3
Johnno Nolan

Beim Filtern der Verknüpfung sehe ich normalerweise eine Leistungssteigerung. Besonders wenn Sie indizierte Spalten für beide Tabellen verknüpfen können. Sie sollten in der Lage sein, logische Lesevorgänge zu reduzieren, da dies bei den meisten Abfragen ebenfalls der Fall ist. Dies ist in einer Umgebung mit hohem Volumen ein viel besserer Leistungsindikator als die Ausführungszeit.

Ich bin immer etwas amüsiert, wenn jemand sein SQL-Benchmarking zeigt und beide Versionen eines Sproc um Mitternacht 50.000-mal auf dem Dev-Server ausgeführt wurden und die Durchschnittszeiten vergleichen.

2
marr75

Das Einfügen der Bedingung in den Join erscheint mir "semantisch falsch", da JOINs nicht "für" sind. Das ist aber sehr qualitativ.

Zusätzliches Problem: Wenn Sie sich entscheiden, von einem inneren Join zu einem rechten Join zu wechseln, kann die Bedingung im JOIN zu unerwarteten Ergebnissen führen.

0
Jacob B

Es ist besser, die Bedingung im Join hinzuzufügen. Leistung ist wichtiger als Lesbarkeit. Bei großen Datensätzen ist es wichtig.

0
Jeeno Shibu

Joins sind meiner Meinung nach schneller, wenn Sie einen größeren Tisch haben. Es ist wirklich kein so großer Unterschied, vor allem wenn es sich um einen eher kleineren Tisch handelt. Als ich zum ersten Mal von Joins erfuhr, wurde mir gesagt, dass die Bedingungen in Joins genau so sind wie die Klauselbedingungen der Klausel, und dass ich sie austauschbar verwenden könnte, wenn die Klausel where die genaue Bedingung für die Tabelle ist.

0
Eric