T-SQL 查询优化之联接顺序

来源:互联网 发布:mcabook软件关不掉 编辑:程序博客网 时间:2024/05/17 06:09

联接顺序,是查询优化的最复杂问题之一,从七十年代以来,一直是广泛探索的主题。随着联接表的增加,搜索空间的扩大,必然导致计划数量的增大。

联接一次只能包括两个表,因此,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 AdventureWorksGOSELECT FirstName, LastNameFROM Person.Contact AS C JOIN Sales.Individual AS I ON C.ContactID = I.ContactID JOIN Sales.Customer AS Cu ON I.CustomerID = Cu.CustomerIDWHERE Cu.CustomerType = 'I'


 

从上面执行计划可以看到,表联接并没有按照T-SQL的输入顺序进行,而是,先CUSTOMER AND INDIVIUDAL,后再联接 CONTACT。

执行如下语句:

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


 

这里,我们强制按照T-SQL联接,但是,开销增大了,第一个占总开销的38%,强制的是62%。

 

最后,应当知道,

1,如果是 左深联接,结果是 N!;

2,如果是 树丛联接,结果是 (2N-2)!/(N-1)!。