首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 書籤查找/鍵值查找/RID 查找移除實戰:覆蓋索引與 INCLUDE 索引

     編輯:關於SqlServer

查詢計畫出現 Key Lookup (Bookmark Lookup/RID Lookup) 表示非叢集索引未覆蓋查詢欄位,需回叢集索引/堆表取值,造成額外 I/O。本文示範兩種移除方案並比較效能。

問題重現

  • 表 Sales.Orders 有叢集索引 orderid
  • 查詢:SELECT orderid, shipaddress, shipregion FROM Sales.Orders WHERE shipcity = '深圳'
  • 建立非叢集索引 IX_shipcity(shipcity) → 產生 Key Lookup 取 shipaddress, shipregion

方案一:覆蓋索引(所有欄位進索引鍵欄)

CREATE NONCLUSTERED INDEX IX_cover ON Sales.Orders(shipcity, orderid, shipaddress, shipregion)

⚠️ 欄位順序關鍵:篩選欄位必須在最前,否則退化為索引掃描。

方案二:INCLUDE 索引(篩選欄位進鍵欄,其餘進包含欄)

CREATE NONCLUSTERED INDEX IX_include ON Sales.Orders(shipcity) INCLUDE(orderid, shipaddress, shipregion)

✅ 鍵欄僅存篩選欄,體積較小、維護成本低,查詢同樣避免 Lookup。

效能比較實測

指標覆蓋索引INCLUDE 索引叢集索引掃描
查詢開銷0.00320.00320.0041
邏輯讀取88124
索引大小較大較小基準

關鍵發現:叢集索引鍵自動包含於非叢集索引

移除 orderid 重測,開銷不變。結論:非叢集索引隱含叢集索引鍵,無需重複宣告。

最佳實務建議

  1. 優先用 INCLUDE 索引:鍵欄只放 WHERE/JOIN/ORDER BY 欄位
  2. 覆蓋索引用於:需對包含欄位再排序/分組時
  3. 監控 sys.dm_db_index_usage_stats 移除未使用索引
  4. 堆表無叢集索引時,RID Lookup 同理可用 INCLUDE 解決

精準設計索引,消除 Lookup,是查詢調優最高 ROI 的動作之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved