9 Stimmen

Verwirrt über die Reihenfolge der logischen Abfrageverarbeitung von Itzik Ben-Gan in seinem SQL Server 2005-Buch und SQL Server 2008-Buch

In dem Buch T-SQL-Abfragen in Microsoft SQL Server™ 2005 Der Autor Itzik Ben-Gan erklärt uns die Reihenfolge der logischen Abfrageverarbeitung von SQL Server 2005:

(8)  SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

1.  FROM
2.  ON
3.  OUTER (join)
4.  WHERE
5.  GROUP BY
6.  CUBE | ROLLUP
7.  HAVING
8.  SELECT
9.  DISTINCT
10. ORDER BY  <---------------------- NOTE
11. TOP       <---------------------- NOTE

In seinem Buch Einblick in Microsoft SQL Server 2008 : T-SQL-Abfragen sagt er uns die folgende logische Reihenfolge der Abfrageverarbeitung:

(1) FROM
(1-J1) Cartesian Product
(1-J2) ON Filter
(1-J3) Add Outer Rows
(2) WHERE
(3) GROUP BY
(4) HAVING
(5) SELECT
(5-1) Evaluate Expressions
(5-2) DISTINCT
(5-3) TOP       <---------------------- NOTE
(6) ORDER BY    <---------------------- NOTE

Beachten Sie die Reihenfolge der TOP y ORDER BY in den oberen Auszügen aus diesen Büchern. Sie sind genau entgegengesetzt. Ich denke, dass diese beiden Schritte sehr wichtig sind und bei einer anderen Reihenfolge zu einem völlig anderen Ergebnis führen würden. Ich möchte wissen, ob SQL Server 2008 etwas in seiner Speicher-Engine von SQL Server 2005 geändert hat oder ob es einen anderen Grund dafür gibt.

Danke.

6voto

Die logische Verarbeitungsreihenfolge ist ebenfalls in diesem Bücher Online Eintrag. Achten Sie auf die Unterscheidung logisch Bearbeitungsauftrag von physisch Bearbeitungsauftrag. Wie der BOL-Eintrag vermerkt:

Die folgenden Schritte zeigen die logische Reihenfolge der Verarbeitung, oder b Bestellung für eine SELECT-Anweisung. Diese Reihenfolge bestimmt, wann die in einem Schritt definierten Objekte die in einem Schritt definiert wurden, den Klauseln in den folgenden Schritten zur Verfügung Schritten zur Verfügung stehen. Wenn der Abfrageprozessor z.B. auf die folgenden Tabellen zugreifen kann Tabellen oder Views zugreifen kann, die in der FROM-Klausel definiert sind, werden diese Objekte und ihre Spalten für alle nachfolgenden Schritte zur Verfügung gestellt. Umgekehrt, da die SELECT-Klausel Schritt 8 ist, werden alle Spaltenalias oder abgeleiteten Spalten, die in dieser Klausel definiert sind, nicht von vorangehenden Klauseln referenziert werden. Sie können jedoch von nachfolgenden Klauseln referenziert werden, wie z. B. die ORDER BY-Klausel. N Anweisung durch den Abfrageprozessor bestimmt wird und die Reihenfolge von dieser Liste abweichen kann.

Dem Abfrageoptimierer steht es frei, die von der Abfrage angegebene logische Anforderung in eine beliebige physisch Ausführungsplan, der die richtigen Ergebnisse liefert. In der Regel gibt es viele physische Alternativen für eine gegebene logische Abfrage, so dass es durchaus üblich ist, dass sich ein physischer Plan grundlegend von der oben beschriebenen logischen Verarbeitungsreihenfolge (zu Bindungszwecken) unterscheidet.

5voto

Will A Punkte 24412

Siehe dies heraus - Es handelt sich um ein Exposé zu diesem Thema - und Itziks Buch wird erwähnt. Die zweite Bestellung oben ist korrekt.

3voto

Mike Punkte 3422

In seinem 2015 veröffentlichten Buch T-SQL-Abfragen Itzik Ben-Gan hat die logische Abfrageverarbeitung in "LISTING 1-1 Logical query-processing step numbers" wie folgt aktualisiert:

(5) SELECT (5-2) DISTINCT (7) TOP(<top_specification>) (5-1) <select_list>
(1) FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <on_predicate> 
       | (1-A) <left_table> <apply_type> APPLY <right_input_table> AS <alias> 
       | (1-P) <left_table> PIVOT(<pivot_specification>) AS <alias> 
       | (1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias> 
(2) WHERE <where_predicate> 
(3) GROUP BY <group_by_specification> 
(4) HAVING <having_predicate> 
(6) ORDER BY <order_by_list> 
(7) OFFSET <offset_specification> ROWS FETCH NEXT <fetch_specification> ROWS ONLY;

Anders als die vorherige Version des Buches von 2008, ORDER BY (Stufe 6 ) tritt nun vor TOP (Stufe 7 ). Natürlich, wie an anderer Stelle erwähnt, sind die beiden miteinander verbunden. Wie Itzik auf Seite 6 von T-SQL-Abfragen :

[TOP] filtert die angegebene Anzahl von Reihenfolge in der ORDER BY-Klausel, o ORDER BY-Klausel nicht vorhanden ist. Mit OFFSET-FETCH überspringt diese Phase die die angegebene Anzahl von Zeilen und filtert dann die nächste angegebene Anzahl von Zeilen auf der Grundlage der Reihenfolge in der ORDER BY-Klausel.

Das Verständnis der obigen logischen Abfrageverarbeitungsschritte ist wichtig, weil es sonst unintuitive Macken in SQL erklärt.

Sie können zum Beispiel keinen Alias aus dem SELECT Klausel (Schritt 5-2 ) im WHERE Klausel (Schritt 2 ), da die Expression Engine die WHERE Klausel vor der SELECT Klausel.

-- This won't work!
SELECT Cost = Quantity * Price
FROM Orders
WHERE Cost > 500.00;

Wie Itzik in seinem Buch sagt: "Die Phasen der logischen Verarbeitung einer Abfrage haben eine bestimmte Reihenfolge. Im Gegensatz dazu kann der Optimierer oft Abkürzungen im physischen Ausführungsplan, den er generiert. Natürlich wird er diese Abkürzungen nur dann vornehmen, wenn die Ergebnismenge garantiert die richtige ist."

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X