it-swarm.com.de

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

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 in der JOIN-Klausel (i.index_id > 0 AND i.is_hypothetical = 0) Verwendet, während die zweite in der WHERE-Klausel dieselbe verwendet. Beeinträchtigt dies die Abfrage oder die Leistung?

7
user960567

Wie JNK sagte, werden diese für einen INNER JOIN Gleich sein. Sie können es beweisen, indem Sie tatsächlich (nicht mit geschätzt) Ausführungsplänen vergleichen. In diesem Fall sind sie genau gleich ( zum Vergrößern klicken ):

(enter image description here

Persönlich möchte ich die Verknüpfungsbedingungen und die Filterbedingungen getrennt halten. Verknüpfungsbedingungen werden in die Klausel ON und Filterbedingungen in die Klausel WHERE aufgenommen. Dies ist einer der Hauptvorteile einer expliziten INNER JOIN - Syntax, die dazu beiträgt, das Risiko zu verringern, dass zu viele Zeilen zurückgegeben werden, weil nicht genug (oder sogar nein ) Verknüpfungskriterien für Verknüpfungen im alten Stil (bei denen Filter- und Verknüpfungskriterien zusammengeführt werden) - siehe weitere Informationen finden Sie in diesem Blog-Beitrag .

JNK hat jedoch auch Recht, dass Sie vorsichtig sein müssen, wenn Sie über OUTER JOIN Sprechen. 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 immer noch alle drei Zeilen von a zurück (wie zu erwarten), die zweite Abfrage verwandelt jedoch OUTER JOIN In einen INNER JOIN. und gibt nur die Zeilen von a mit einer Übereinstimmung von b unter all 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.

9
Aaron Bertrand