前言
叢集索引決定了資料表的物理儲存順序,每張表僅能擁有一個。正確選擇叢集索引鍵是效能調校的關鍵決策。本文剖析叢集索引優於非叢集索引的兩大核心原因,並提供候選欄位選擇指南與避坑原則。
一、 叢集索引為何更快?兩大核心優勢
- 結構緊湊,免除書籤查找: 叢集索引葉層即為資料頁,僅含指向頁的指標,不像非叢集索引需額外儲存 Row Identifier (RID) 或叢集鍵值進行二次查找。體積更小,頁讀取更少。
- 資料物理有序,範圍掃描極致高效: 符合條件的資料列物理相鄰。SQL Server 定位首筆符合列後,順序掃描頁面即可取得所有結果。對於大結果集範圍查詢,避免了非叢集索引反覆書籤查找的隨機 I/O 開銷。
二、 叢集索引鍵選擇四大黃金標準
理想叢集鍵應具備:窄、唯一、不變、遞增。
- 窄: 鍵值越短,非叢集索引頁面容納行數越多,樹高越矮,I/O 越少。
- 唯一: 避免 SQL Server 內部添加 4-byte 唯一化器,增加儲存與維護成本。
- 不變: 叢集鍵更新會導致整行資料物理移動,並觸發所有非叢集索引更新(因其書籤指向叢集鍵),代價極大。
- 遞增: 新資料追加在末尾,減少頁分裂與碎片,寫入效能最佳。
三、 最佳候選欄位類型
- 高頻範圍查詢欄位: 如
WHERE Price BETWEEN 10 AND 20、WHERE OrderDate > '2023-01-01'。
- ORDER BY / GROUP BY 高頻欄位: 資料預排序,省去排序運算子。
- JOIN 連接欄位 (非主鍵): 大量連接時,叢集索引較小、查找頁數少,累積效益顯著。
- 具隨機分佈特性的業務欄位: 出生日期、姓名、郵遞區號、雜湊值等,分散插入熱點。
四、 避坑指南:拒絕單調遞增鍵 (如 Identity) 做叢集索引
雖 Identity 滿足「窄、唯一、遞增」,但會在表尾製造「熱點」,導致:
- 鎖競爭與死鎖頻發 (PAGELATCH_EX 等待)。
- 空間浪費:舊資料刪除釋放的頁面無法被新遞增鍵重用 (因新資料只往尾部插)。
對策: 主鍵改用非叢集唯一索引維護實體完整性;叢集索引選擇業務上具隨機分佈的欄位。
五、 實務決策矩陣
| 場景 | 建議策略 |
| 單一索引預算 | 優先建叢集索引,修改/插入/刪除開銷比非叢集小 |
| 主鍵為單點查找 (PK Lookup) | 主鍵建非叢集唯一索引;叢集索引讓給範圍查詢/JOIN/排序欄位 |
| 主鍵為 Identity | 主鍵 = 非叢集 PK;叢集索引選隨機業務鍵 (如 CreateDate + ClientID 組合) |