2013-03-04 14 views
6

Wenn ich eine Abfrage wie folgt aus:Wann findet die WHERE-Filterung statt?

SELECT 
    A.ID, 
    A.Name, 
    A.Type, 
    B.FirstName, 
    B.LastName, 
    B.DateOfBirth, 
    C.OfficeName 
FROM A 
    INNER JOIN B ON A.ContactID = B.ID 
    INNER JOIN C ON B.OfficeID = C.ID 
WHERE 
    A.Type = 1 

Wann tritt der A.Type = 1 Filter angewandt werden? Ist es nach den Joins oder fragt die Abfrage nach 'A', ob es den Filter übergibt und dann nur zu B und C, wenn dies der Fall ist?

Hope das macht Sinn. Vielen Dank.

+1

Können Sie einen Abfrageausführungsplan enthalten? Das wird wahrscheinlich deine Frage beantworten. – mellamokb

+1

Ich hatte immer den Eindruck, dass der Abfrageoptimierer es herausgefunden und dort angewendet hat, wo es am optimalsten (oder nahe wie) war. Führen Sie die Abfrage mit der Option "Tatsächlichen Abfrageplan einbeziehen" aus, die in SSMS aktiviert ist, um zu sehen, was passiert. –

+0

Ändert es etwas? Solange die Ergebnisse stimmen, natürlich. SQL Server wird es so machen, wie es effizienter ist. – MarcinJuraszek

Antwort

8

mit zu beginnen, unten ist die SQL-Reihenfolge der Vorgänge:

  • FROM-Klausel
  • WHERE-Klausel
  • GROUP BY-Klausel
  • HAVING-Klausel
  • SELECT-Klausel
  • ORDER BY-Klausel

In einer einfachen Abfrage erfolgt die Filterung nach der FROM Klausel (Joins finden Sie in diesem Teil). Was Sie oben tun, ist, dass es in erster Linie die Tabellen mit ihren verknüpfenden Spalten verbindet, die ihre Beziehung definieren. Nach den Aufzeichnungen eingestellt wurde (das Ergebnis Joins) die WHERE Klausel erfolgt dann Type, um herauszufiltern, wo ist 1.


Hier gleich ein weiteres Beispiel von LEFT JOIN verwenden,

Erste Abfrage:

SELECT A.ID, 
     A.Name, 
     A.Type, 
     B.FirstName, 
     B.LastName, 
     B.DateOfBirth 
FROM A 
     LEFT JOIN B 
      ON A.ContactID = B.ID AND 
       B.LastName = 'Michaels' 

vs Zweite Frage:

SELECT A.ID, 
     A.Name, 
     A.Type, 
     B.FirstName, 
     B.LastName, 
     B.DateOfBirth 
FROM A 
     LEFT JOIN B ON A.ContactID = B.ID 
WHERE B.LastName = 'Michaels' 

Die erste Abfrage gibt ALLE Datensätze aus der Tabelle A zurück. Was B.LastName = 'Michaels' tut ist, bevor die Tabelle B mit der Tabelle A verbunden wird, filtert sie alle Datensätze aus, in denen LastName gleich Michaels ist. Die Datensätze aus der Tabelle A, die keine Übereinstimmungen mit den gefilterten Datensätzen in der Tabelle B aufweisen, haben die Werte NULL in den Spalten aus der Tabelle B.

Die zweite Abfrage liefert nicht das gleiche Ergebnis mit der ersten Abfrage und führt genau dasselbe mit INNER JOIN aus, da nach dem Verknüpfen der Datensätze eine weitere Filterung für das Ergebnis ausgeführt wird und nur die Datensätze übernommen werden, für die LastName gleich ist Michaels.

6

Logisch - nach join s, physisch - es ist bis zum Optimierer.

2

Um dies zu beantworten, müssen Sie sich wirklich den Ausführungsplan ansehen. Falls Sie erwähnen, dass Sie in der where-Klausel ein durchsuchbares Argument (ein SARG) haben, wird der Filter höchstwahrscheinlich mit Ihrer Zugriffsmethode, d. H. Index, Tabellenscan usw., vor dem Join angewendet.

Verwenden

Abfrage-Menü -> Neue Ist-Ausführungsplan

oder

Menü Abfrage -> Anzeigen Geschätzte Ausführungsplan

einen Blick nehmen .

4

Pro MSDN.
Überprüfen Sie den Abschnitt Logical Verarbeitungsreihenfolge der SELECT-Anweisung

  1. VON
  2. ON
  3. Titel
  4. JOIN
  5. WHERE
  6. GROUP BY
  7. MIT CUBE oder WITH ROLLUP
  8. HABEN
  9. SELECT
  10. DISTINCT
  11. ORDER BY
  12. TOP

Dort am Ende des Absatzes vor dieser Liste ein wichtiger Hinweis ist.

Beachten Sie, dass die tatsächliche physische Ausführung der Anweisung vom Abfrageprozessor bestimmt wird und die Reihenfolge von dieser Liste abweichen kann.

1

Where-Klausel angewendet wird, bevor beitreten das heißt, es werden alle Zeilen von A zurückkehren und die entsprechenden Zeilen von B und C hängen von Join-Bedingung und für type = 1

Verwandte Themen