問:使用NC掃描運算符,有方法知道索引是怎么掃描的么?
這個問題的一個答案是非聚集索引掃描總是掃描整個索引。
答:是的,總是100%。掃描運算符總是整個索引……
但是有一些特定的情況并不是這樣。在這篇文章里我想專門講下你總會碰到的一個特定案例——在你的查詢里有TOP,MIN或者MAX表達式。
TOP,MIN,MAX我們來看下面2個查詢。
1 SELECT TOP 10 * FROM Person.Person2 GO3 4 SELECT5 MIN(BusinessEntityID) AS 'Min',6 MAX(BusinessEntityID) AS 'Max'7 FROM Person.Person8 GO
第1個查詢從Person .Person表返回前10行,第2個查詢返回BusinessEntityID列的最小和最大值。當(dāng)你看執(zhí)行計劃結(jié)果時,你會看到有趣的東西:
第1個查詢“掃描”聚集索引來獲得前10行,對于第2個查詢,聚集索引也被“掃描”2次來獲得BusinessEntityID的最小值和最大值。但在這些情況里聚集索引掃描(Clustered Index Scan)并不是真正的聚集索引全掃描,因為TOP運算符縮短了聚集索引掃描(Clustered Index Scan)。這是什么意思呢?
一般來說,你知道你應(yīng)該從右到左閱讀執(zhí)行計劃,因為執(zhí)行計劃里的行也是從右流向左的。但在執(zhí)行計劃執(zhí)行期間,是從左往右執(zhí)行的。SQL Server內(nèi)部使用所謂的迭代器模式(Iterator-Model),在那里執(zhí)行計劃里每個運算符從右邊的運算符請求新的行。下圖說明了這個非常重要的概念。
因為這個迭代器,最后的數(shù)據(jù)流是從右到左。現(xiàn)在當(dāng)你看剛才生成的執(zhí)行計劃,你可以看到TOP運算符有所謂的TOP表達式(Top ExPRession):
對于第1個查詢TOP表達式是10,對于第2個執(zhí)行計劃里的2個TOP表達式是1。這個TOP表達式就定義TOP運算符消耗從右邊的輸入運算符的行數(shù)。當(dāng)?shù)?個查詢里TOP運算符已消耗10行(前10行)后,TOP運算符就會縮短執(zhí)行計劃,且不會返回更多的行給SELECT運算符,這就意味著查詢執(zhí)行計劃已經(jīng)最終結(jié)束了。
同樣的事情發(fā)生在第2個執(zhí)行計劃。為了獲得BusinessEntityID的最小值(聚集鍵值),TOP運算符只消耗來自向前聚集索引掃描(Forward Clustered Index Scan)的第1行,最大值只消耗來自向后聚集索引掃描(Backward Clustered Index Scan)的第1行。
小結(jié)當(dāng)你在執(zhí)行計劃里看到TOP運算符,你總要想下這個特定場景:TOP運算符只會縮短你的掃描運算符。因此結(jié)論就是:在執(zhí)行計劃里,掃描并不總是掃描。
感謝關(guān)注!
新聞熱點
疑難解答
圖片精選