2009-08-05 6 views
2

Wenn Sie zwei Tabellen verbinden, was ist der Unterschied zwischen den beiden folgenden Blöcken und welcher ist der bessere Ansatz?Welche SQL schreiben Sie?

Muster A:

SELECT ... 
FROM A 
    INNER JOIN B 
     ON A.PK = B.FK 
WHERE 1=1 
    AND A.Name = "Foo" 
    AND B.Title = "Bar" 

Muster B:

SELECT ... 
FROM A 
    INNER JOIN B 
     ON A.PK = B.FK 
      AND B.Title = "Bar" 
WHERE 1=1 
    AND A.Name = "Foo" 
+2

Ich würde denken, die Abfrage optimzier könnte nicht weniger interessieren; aber ich bin kein Guru ... – balpha

+0

@balpha: das stimmt nur für * INNER * Joins. Es gibt einen Unterschied für OUTER Joins. – Sung

Antwort

13

Das wird von Person zu Person unterscheiden, aber ich denke, dass Muster A besser ist.

Was es tut, ist es trennt die Tabellenebene Joins von den Filtern. Dies könnte für Abfragen mit mehreren Joins und mehreren Filtern hilfreich sein, da die beiden Arten von Joining, die gerade stattfinden, klar voneinander getrennt sind.

+0

Genau. ON wurde ursprünglich eingeführt, um Join-Bedingungen von Filtern zu trennen. – Powerlord

4

Ich bevorzuge Muster A, aber es gibt wahrscheinlich keinen Unterschied. Sie müssen sich jedoch wirklich den Ausführungsplan ansehen, um sicherzustellen, dass er effizient ausgeführt wird.

0

Ich könnte falsch liegen, aber ich sehe den ersten Ansatz als effizienter. Ihre Abfragen werden von innen nach außen ausgeführt. Wenn Sie Ihren Join also zuerst ausführen, wird er schneller ausgeführt, nur weil er auf PK-Feldern (und wahrscheinlich indiziert) PK & FK-Feldern und nicht etwas anderem wie Ihrem Title-Feld (was wahrscheinlich ein Varchar ist, wodurch die Übereinstimmung noch langsamer wird). Wenn Sie also zu Ihrer filterischen where-Klausel kommen, haben Sie weniger Daten, um die Übereinstimmung zu erreichen. Totale Spekulation obwohl. Ich frage mich, was andere sagen würden. Würde nicht weh tun, um den Ausführungsplan zu sehen :)

+1

Bei der Kopplung mit einer guten Abfragemethode sollte die Art und Weise, in der eine Abfrage geschrieben wird, nicht mit der Ausführung der Abfrage korreliert sein. Dies könnte bei älteren, weniger cleveren Abfrage-Engines zutreffen. –

3

Wenn Sie INNER JOIN durch OUTER JOIN ersetzen, wird es einen Unterschied geben.

Andernfalls diese Abfragen:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  A.PK = B.FK 
WHERE A.Name = "Foo" 
     AND B.Title = "Bar" 

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  A.PK = B.FK 
     AND B.Title = "Bar" 
WHERE A.Name = "Foo" 

SELECT * 
FROM A, B 
WHERE B.Title = "Bar" 
     AND A.Name = "Foo" 
     AND A.PK = B.FK 

identisch sind.

Oracle, MySQL, PostgeSQL und SQL Server wird behandeln sie genau das gleiche, und verwenden genau denselben Plan für alle von ihnen.

würde ich dies verwenden:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  B.FK = A.PK 
WHERE A.Name = "Foo" 
     AND B.Title = "Bar" 

wenn es eine einspaltige Taste auf B.FK ist, und diese:

SELECT ... 
FROM A 
INNER JOIN 
     B 
ON  B.FK = A.PK 
     AND B.Title = "Bar" 
WHERE A.Name = "Foo" 

, wenn es ein zusammengesetzter Schlüssel auf (B.FK, B.title) ist.

Die Join-Bedingungen sind in diesem Fall sichtbarer.

+0

Sie haben absolut recht, dass es einen Unterschied gibt, wenn Sie einen äußeren Join verwenden, da das erste Muster den äußeren Join zu einem inneren Join konvertiert und der zweite nicht, so dass die Ergebnisse sehr unterschiedlich sein werden. – HLGEM

Verwandte Themen