Key Lookup開銷過大導致聚集索引掃描


以前總結過一篇文章SQL SERVER中什么情況會導致索引查找變成索引掃描 介紹了幾種索引查找(Index Seek)變成索引掃描(Index Scan)的情形。昨天寫一篇文章的時候,也遇到了一個讓人奇怪的執行計划。一時沒有想明白為什么優化器會選擇聚集索引掃描。案例詳情請見SQL Server OPTION (OPTIMIZE FOR UNKNOWN) 測試總結  如下所示,測試環境為SQL Server 2014,數據庫為AdventureWorks2014

 

 

CREATE PROCEDURE test (@pid int)

AS

SELECT * FROM [Sales].[SalesOrderDetail]

WHERE ProductID = @pid OPTION (OPTIMIZE FOR UNKNOWN);

 

 

clip_image001

 

 [Sales].[SalesOrderDetail]的索引信息如下如下。其實這里優化器選擇聚集索引掃描是因為Cost緣故。因為走非聚集索引查找(Index Seek)的話,Key Lookup的開銷較大。整體開銷比聚集索引掃描還大。我們可以測試驗證一下

 

clip_image002

 

 

如下所示,我們新增一個SQL語句,強制其走索引查找(具體索引為IX_SalesOrderDetail_ProductID),然后執行對比查看執行計划的開銷

 

 

 

ALTER PROCEDURE test (@pid int)

AS

SELECT * FROM [Sales].[SalesOrderDetail]

WHERE ProductID = @pid OPTION (OPTIMIZE FOR UNKNOWN);

 

SELECT * FROM [Sales].[SalesOrderDetail] WITH (INDEX =IX_SalesOrderDetail_ProductID)

WHERE ProductID = @pid;

GO

 

 

如下測試所示,兩種實際執行計划的開銷比為 22%  VS  78%  所以優化器肯定會選開銷小的執行計划。也就是說如果優化器發現當索引查找時,如果Key Lookup開銷過大,那么優化器會選擇聚集索引索引掃描。 這個案例就是一個活生生的案例。 也許有人會反問:不是Index Seek效率表Index Scan要高嗎?你這有點不合邏輯,注意,這個特定條件下,雖然Index Seek變成 Index Scan,但是你注意一下上下文,索引變了, 從IX_SalesOrderDetail_ProductID變成了聚集索引PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID 。

 

 

 

clip_image003

 

 

總結: 任何現象背后都有一定的規律,有時候,只要你靜下心來,仔細分析一下。就能一窺究竟。如果總是不問為什么,那么你總是不了解背后原理!也就永遠止步不前!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM