Es ist besser, eine Bedingung für eine Tabelle in JOIN zu setzen?

8

Ich habe oft gesehen, dass Leute die JOIN-Klausel mit tabellenbezogenen Bedingungen versehen. Siehe dieses Beispiel,

SELECT i.Name
  FROM sys.TABLES AS tbl
  INNER JOIN sys.indexes AS i
    ON (i.index_id > 0 AND i.is_hypothetical = 0) 
    AND (i.object_id = tbl.object_id)
  WHERE (i.is_unique = 1 AND i.is_disabled = 0) 
    AND (tbl.Name = 'Warehouse')


SELECT i.Name
  FROM sys.TABLES AS tbl
  INNER JOIN sys.indexes AS i
    ON (i.object_id = tbl.object_id)
  WHERE (i.index_id > 0 AND i.is_hypothetical = 0) 
  AND (i.is_unique = 1 AND i.is_disabled = 0) 
  AND (tbl.Name = 'Warehouse')

Die Abfrage ist dieselbe, aber der Unterschied besteht darin, dass die erste (i.index_id > 0 AND i.is_hypothetical = 0)in der JOIN-Klausel verwendet wird, während die zweite dieselbe in der WHERE-Klausel verwendet. Beeinträchtigt dies die Abfrage oder die Leistung?

user960567
quelle
4
Die einzige Möglichkeit, dies sicher zu wissen, besteht darin, Ausführungspläne für beide Abfragen abzurufen. Ich kann mir vorstellen, dass sie gleich sein werden. Für eine INNER JOINsind das gleichwertige Abfragen. Wenn Sie OUTER JOINdie Bedingung auf die Verknüpfungsbedingung anstatt auf die setzen WHERE, ändern sich Ihre Ergebnisse. Seien Sie also vorsichtig.
JNK

Antworten:

10

Wie JNK sagte, INNER JOINwerden diese zum einen gleich sein. Sie können dies beweisen, indem Sie die tatsächlichen (nicht mit geschätzten ) Ausführungspläne vergleichen. In diesem Fall sind sie genau gleich ( zum Vergrößern anklicken ):

Geben Sie hier die Bildbeschreibung ein

Persönlich möchte ich die Verknüpfungsbedingungen und die Filterbedingungen getrennt halten. Join-Bedingungen werden in die ONKlausel und Filterbedingungen in die WHEREKlausel aufgenommen. Dies ist einer der Hauptvorteile einer expliziten INNER JOINSyntax, die dazu beiträgt, das Risiko zu verringern, dass zu viele Zeilen zurückgegeben werden, da Joins im alten Stil nicht genügend (oder gar keine ) Join-Kriterien enthalten (Filter- und Join-Kriterien) werden zusammengeworfen) - siehe diesen Blog-Beitrag für weitere Details .

JNK hat aber auch Recht, dass Sie vorsichtig sein müssen, wenn Sie darüber sprechen OUTER JOIN. Ein einfaches Beispiel:

CREATE TABLE dbo.a(id INT);

CREATE TABLE dbo.b(id INT, name SYSNAME);

INSERT dbo.a(id) VALUES(1),(2),(3);

INSERT dbo.b(id) VALUES(2,N'a'),(3,N'b');

SELECT a.id, b.name 
  FROM dbo.a 
  LEFT OUTER JOIN dbo.b
  ON a.id = b.id 
  AND b.name LIKE N'b%';

SELECT a.id, b.name
  FROM dbo.a 
  LEFT OUTER JOIN dbo.b
  ON a.id = b.id 
  WHERE b.name LIKE N'b%';
--^^^^^ only difference

DROP TABLE dbo.a, dbo.b;

Ergebnisse:

id    name
----  ----
1     NULL
2     NULL
3     b

id    name
----  ----
3     b

Wie Sie den Ergebnissen entnehmen können, gibt die erste Abfrage weiterhin alle drei Zeilen von zurück a(wie zu erwarten), die zweite Abfrage verwandelt jedoch die OUTER JOINin eine INNER JOINund gibt nur die Zeilen von amit einer Übereinstimmung von bunter allen Bedingungen zurück. Möglicherweise möchten Sie das eine oder andere Verhalten, daher ist keines davon "schlechter" oder "falsch". Es ist nur wichtig, die verschiedenen Funktionen zu verstehen, damit Sie die Abfrage schreiben können, um die gewünschten Ergebnisse zu erzielen.

Aaron Bertrand
quelle