T-SQL 查詢優化之聯接順序

聯接順序,是查詢優化的最複雜問題之一,從七十年代以來,一直是廣泛探索的主題。隨着聯接表的增加,搜索空間的擴大,必然導致計劃數量的增大。

聯接一次只能包括兩個表,因此,N個表聯接有 N-1次聯接。當然,下一個聯接不需要等到上一個聯接完成。

兩個屬性:

1,交換

A JOIN B = B JOIN A

它確定那個表作爲第一個表,例如,在 NESTED LOOP JOIN 中,第一個表是作爲外部表,第二個是內部表;在 HASH JOIN 中,第一個表作爲 BUILD,第二個是 PROBE。

2,相關

(A JOIN B) JOIN C = A JOIN (B JOIN C)

它確定表聯接的順序,例如,等號左邊,首先 A JOIN B,然後中間結果再聯接 C,而右邊是,先 B JOIN C,後結果再聯接A。

 

毫無疑問,聯接的交換和相關屬性,產生了表聯接的不同排列,而每個排列的開銷是不同的,當然,最終的決定在於查詢優化器。

 

好吧,看個例子:

USE AdventureWorks
GO
SELECT FirstName, LastName
FROM Person.Contact AS C 
JOIN Sales.Individual AS I ON C.ContactID = I.ContactID 
JOIN Sales.Customer AS Cu ON I.CustomerID = Cu.CustomerID
WHERE Cu.CustomerType = 'I'


 

從上面執行計劃可以看到,表聯接並沒有按照T-SQL的輸入順序進行,而是,先CUSTOMER AND INDIVIUDAL,後再聯接 CONTACT。

執行如下語句:

SELECT FirstName, LastName
FROM Person.Contact AS C 
JOIN Sales.Individual AS I ON C.ContactID = I.ContactID 
JOIN Sales.Customer AS Cu ON I.CustomerID = Cu.CustomerID
WHERE Cu.CustomerType = 'I'
OPTION (FORCE ORDER)


 

這裏,我們強制按照T-SQL聯接,但是,開銷增大了,第一個佔總開銷的38%,強制的是62%。

 

最後,應當知道,

1,如果是 左深聯接,結果是 N!;

2,如果是 樹叢聯接,結果是 (2N-2)!/(N-1)!。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章