對于T-SQL編程,用得最廣泛的,莫過于查詢(Querying)。要想寫出高質量、高性能的查詢語句,必須深入地了解邏輯查詢處理。
一、邏輯查詢處理的各個階段
(5)SELECT DISTINCT TOP(<top_specification>) <select_list>
(1)FROM <left_table> <join_type> JOIN <right_table> ON <on_PRedicate>
(2)WHERE <where_predicate>
(3)GROUP BY <group_by_specification>
(4)HAVING <having_predicate>
(6)ORDER BY <order_by_list>
上邊語句是一個普通格式的查詢語句,基本包含了所有的查詢條件和關鍵字。你可能會發現前邊的序號并不是按順序來的,被你說對了,這是SQL與其他編程語言不同的最明顯特征,就是它的執行順序并不是按照編寫順序來的。上邊的序號,就是查詢語句在執行過程中的邏輯處理順序。下面簡單介紹一下各個階段都干了啥事。
(1)FROM 階段
FROM階段標識出查詢的來源表,并處理表運算符。在涉及到聯接運算的查詢中(各種join),主要有以下幾個步驟:
a.求笛卡爾積。不論是什么類型的聯接運算,首先都是執行交叉連接(cross join),求笛卡兒積,生成虛擬表VT1-J1。
b.ON篩選器。這個階段對上個步驟生成的VT1-J1進行篩選,根據ON子句中出現的謂詞進行篩選,讓謂詞取值為true的行通過了考驗,插入到VT1-J2。
c.添加外部行。如果指定了outer join,還需要將VT1-J2中沒有找到匹配的行,作為外部行添加到VT1-J2中,生成VT1-J3。
經過以上步驟,FROM階段就完成了。概括地講,FROM階段就是進行預處理的,根據提供的運算符對語句中提到的各個表進行處理(除了join,還有apply,pivot,unpivot)
(2)WHERE階段
WHERE階段是根據<where_predicate>中條件對VT1中的行進行篩選,讓條件成立的行才會插入到VT2中。
(3)GROUP BY階段
GROUP階段按照指定的列名列表,將VT2中的行進行分組,生成VT3。最后每個分組只有一行。
(4)HAVING階段
該階段根據HAVING子句中出現的謂詞對VT3的分組進行篩選,并將符合條件的組插入到VT4中。
(5)SELECT階段
這個階段是投影的過程,處理SELECT子句提到的元素,產生VT5。這個步驟一般按下列順序進行
a.計算SELECT列表中的表達式,生成VT5-1。
b.若有DISTINCT,則刪除VT5-1中的重復行,生成VT5-2
c.若有TOP,則根據ORDER BY子句定義的邏輯順序,從VT5-2中選擇簽名指定數量或者百分比的行,生成VT5-3
(6)ORDER BY階段
根據ORDER BY子句中指定的列明列表,對VT5-3中的行,進行排序,生成游標VC6.
當然SQL SERVER在實際的查詢過程中,有查詢優化器來生成實際的工作計劃。以何種順序來訪問表,使用什么方法和索引,應用哪種聯接方法,都是由查詢優化器來決定的。優化器一般會生成多個工作計劃,從中選擇開銷最小的那個去執行。邏輯查詢處理都有非常特定的順序,但是優化器常常會走捷徑。
新聞熱點
疑難解答