我們知道,查詢的邏輯處理過程是分階段完成的,每個階段都會產生一個虛擬表,該虛擬表會作為下一個階段的輸入。但是,這些過程中間階段生成的虛擬表對於查詢用戶是不可用的,只有最後階段所生成的虛擬表(即查詢結果)才返回給查詢用戶。
在該書的SQL Server 2005版本中,將一個聯接查詢的邏輯處理分為了10個步驟:
(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>
而在SQL Server 2008版本中,則對邏輯階段的描述擴展到了所有的邏輯語句,而不僅僅是聯接處理,如APPLY、PIVOT等。按這種分類方式,將邏輯步驟分成了6部分,部分步驟中包含了子步驟。
(5)SELECT (5-2)DISTINCT (5-3)<TOP_specification> (5-1)<select_list>
(1)FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <join_condition>
|(1-A) <left_table> <apply_type> APPLY <right_table_expression> AS <alias>
|(1-P) <left_table> PIVOT(<pivot_specifications>) AS <alias>
|(1-U) <left_table> UNPIVOT(<unpivot_specifications>) AS <alias>
(2)WHERE <where_condition>
(3)GROUP BY <group_by_list> (3-CR)WITH {CUBE | ROLLUP}
(4)HAVING <having_condition>
(6)ORDER BY <order_by_list>
下圖更詳細地描述了各個處理步驟的流程。
這種步驟分類相比2005版本而言更加全面和具體。上面步驟中的3-CR是我添加上去的,我覺得這樣的描述更加全面。3-CR中的WITH ROLLUP和WITH CUBE參數,在SQL Server 2008中已經被GROUP BY子句的GROUPING SETS、ROLLUP和CUBE運算符代替,不再推薦使用不符合ISO標准的WITH ROLLUP、WITH CUBE和ALL語法。但是,這並不影響邏輯處理的順序。
下面是對邏輯處理過程中各個步驟的說明,請注意虛擬表(VTn)的生成步驟:
· 步驟1(FROM):該步驟中用於驗證查詢的源表,並處理表操作符。每個表操作符應用於一系列子步驟。例如,在上面用於聯接的(1-J)步驟中會涉及如下的子步驟。最終這些子步驟完成後,將生成虛擬表VT1。
Ø (1-J1):執行left_table和right_table兩個表的交叉聯接(笛卡兒乘積),生成虛擬表VT1-J1;
Ø (1-J2):對笛卡兒乘積應用ON篩選器,生成虛擬表VT1-J2;
Ø (1-J3):如果是外部聯接,會在該步驟中將被ON篩選掉的外部行添加到VT1-J2中,生成VT1-J3。否則,將跳過該步驟。
· 步驟2(WHERE):對VT1應用WHERE篩選器,將符合篩選條件的行插入到VT2中。
· 步驟3(GROUP BY):按GROUP BY子句中的列列表對VT2中的行分組,生成VT3。如果語句中包含WITH CUBE或WITH ROLLUP,則將分組統計結果再次加總後插入VT3,生成VT3-RC。
· 步驟4(HAVING):對VT3應用HAVING篩選器,將符合篩選條件的行插入到VT4。
· 步驟5(SELECT):處理SELECT子句中的元素,生成VT5。
u (5-1)計算表達式:該步驟計算SELECT列表中的表達式,生成VT5-1;
u (5-2)DISTINCT:從VT5-1中移除重復行,生成VT5-2;
u (5-3)TOP:該步驟根據ORDER BY子句中指定的排序規則,從VT5-2的開始處篩選出指定數量或比例的行。
· 步驟6(ORDER BY):該步驟對VT5-3中的行按ORDER BY子句中的列列表進行排序,生成一個游標VC6。