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

SQL Server 索引 INCLUDE 欄位 (包含欄位) 的魅力:覆蓋查詢、避免 Key Lookup、縮小索引體積

     編輯:關於SqlServer

非叢集索引的葉層「夾帶私貨」:INCLUDE 讓覆蓋查詢更輕量

SQL Server 2005 引入 **Non-Key Columns (INCLUDE Columns)**,僅儲存在索引葉層,**不計入鍵長度 900 bytes 限制、不影響排序、不參與統計資料密度計算**,專為覆蓋查詢設計。

核心概念速查

術語定義
覆蓋查詢查詢引用的所有欄位皆包含於索引中 (鍵欄位 + INCLUDE 欄位 + 叢集鍵),無需回表 (Key Lookup/RID Lookup)。
索引覆蓋同覆蓋查詢,強調「找到索引項即找到所有資料」。
複合索引鍵欄位 ≥ 2 的索引,所有鍵欄位皆在所有層級 (根/中間/葉) 儲存。
非鍵欄位 (INCLUDE)僅在葉層儲存,不影響 B+ 樹排序結構。

INCLUDE vs 複合索引 (鍵欄位化)

面向INCLUDE 欄位加入鍵欄位 (複合索引)
索引體積**較小** (非鍵欄位僅葉層存一次)較大 (所有層級重複儲存)
鍵長度限制**不計入 900 bytes**計入,易超限
排序影響**無**影響 (新增排序鍵)
統計資料不建立密度/直方圖建立完整統計
資料型別限制**支援 LOB (MAX、XML、CLR 等)**不支援 LOB 型別
維護成本略低 (葉層寫入)略高 (所有層級)

實戰範例

-- 查詢:SELECT OrderID, CustomerID, OrderDate, TotalAmount FROM Orders WHERE CustomerID = @Cust AND OrderDate BETWEEN @D1 AND @D2;

-- 方案 A:複合索引 (CustomerID, OrderDate, OrderID, TotalAmount) — 鍵長度可能超限、TotalAmount 若為 MONEY 尚可,若為 XML 則不可
-- 方案 B:INCLUDE 覆蓋索引 (推薦)
CREATE NONCLUSTERED INDEX IX_Orders_Cust_Date_Cover
ON Orders (CustomerID, OrderDate)           -- 鍵欄位:支援 Seek + 範圍掃描 + 排序
INCLUDE (OrderID, TotalAmount);             -- 非鍵欄位:覆蓋 SELECT 列表,避免 Key Lookup

適用場景檢核

  • ☐ 查詢有 **固定 SELECT 列表**,且 `WHERE/JOIN/ORDER BY` 欄位固定。
  • ☐ 需覆蓋 **LOB 型別欄位** (`VARCHAR(MAX)`, `NVARCHAR(MAX)`, `VARBINARY(MAX)`, `XML`)。
  • ☐ 想避免 **Key Lookup** 但不想把欄位加入鍵 (影響排序/統計/長度)。
  • ☐ 索引已接近 900 bytes 鍵長度上限,需再覆蓋幾欄位。

監控覆蓋效果

-- 查看是否出現 Key Lookup
SET STATISTICS IO, TIME ON;
SELECT ... FROM ... WHERE ...;

-- 若輸出含 "Table 'Orders'. Scan count 1, logical reads 3" (無 Lookup) → 覆蓋成功
-- 若含 "Table 'Orders'. Scan count 1, logical reads 103" + "Index Seek -> Key Lookup" → 未覆蓋

結語

**INCLUDE = 覆蓋查詢的輕量級超級武器**。用對場景,能以 **極小索引體積增量** 換取 **巨大查詢效能躍升** (消除 Key Lookup、減少邏輯讀、避免排序)。設計索引時,**先定鍵欄位 (Seek/排序)、再加 INCLUDE (覆蓋)**,別貪多把所有欄位塞進鍵裡。

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