SQL Server 2005 引入 **Non-Key Columns (INCLUDE Columns)**,僅儲存在索引葉層,**不計入鍵長度 900 bytes 限制、不影響排序、不參與統計資料密度計算**,專為覆蓋查詢設計。
| 術語 | 定義 |
|---|---|
| 覆蓋查詢 | 查詢引用的所有欄位皆包含於索引中 (鍵欄位 + INCLUDE 欄位 + 叢集鍵),無需回表 (Key Lookup/RID Lookup)。 |
| 索引覆蓋 | 同覆蓋查詢,強調「找到索引項即找到所有資料」。 |
| 複合索引 | 鍵欄位 ≥ 2 的索引,所有鍵欄位皆在所有層級 (根/中間/葉) 儲存。 |
| 非鍵欄位 (INCLUDE) | 僅在葉層儲存,不影響 B+ 樹排序結構。 |
| 面向 | 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
-- 查看是否出現 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 (覆蓋)**,別貪多把所有欄位塞進鍵裡。