聚集索引(Clustered Index): 資料頁**物理順序**與索引順序一致,資料即索引,葉層即資料頁。每表**僅一個**。
非聚集索引(Nonclustered Index):** 獨立索引結構,葉層儲存**索引鍵值 + 書籤**(RID 或聚集索引鍵),需回查資料頁。每表可建**多個**。
| 動作/特徵 | 聚集索引 | 非聚集索引 |
|---|---|---|
| 欄位經常 GROUP BY / ORDER BY | ✅ 適合 | ✅ 適合 |
| 範圍查詢 (BETWEEN, >, <, >=, <=) | ✅ 適合 | ❌ 不適合 |
| 極少數相同值 (如性別、狀態) | ❌ 不適合 | ❌ 不適合 |
| 少數相同值 (如部門、類別) | ✅ 適合 | ❌ 不適合 |
| 大量相同值 (如流水號、交易ID) | ❌ 不適合 | ✅ 適合 |
| 頻繁 UPDATE 的欄位 | ❌ 不適合 (頁分裂) | ✅ 適合 |
| 外鍵欄位 | ✅ 適合 | ✅ 適合 |
| 主鍵欄位 | ✅ 適合 | ✅ 適合 |
| 頻繁修改索引鍵值 | ❌ 不適合 | ✅ 適合 |
真相: SQL Server 主鍵預設建聚集索引,但**主鍵常為無意義自增 ID**,業務查詢從不按 ID 範圍查,導致寶貴的聚集索引被浪費。
建議: 聚集索引給**業務範圍查詢高頻欄位**(如 交易日期、用戶ID+日期),主鍵改非聚集。
真相: 同一欄位(日期),非聚集索引查 3 個月資料 54 秒,**聚集索引僅 2 秒**(1000 萬筆測試)。索引類型選擇比是否建立更關鍵。
真相: 複合聚集索引 (日期, 用戶):
- WHERE 日期 > ... → 2.5 秒(最左列單獨用)
- WHERE 日期 > ... AND 用戶 = ... → 2.5 秒(全用)
- WHERE 用戶 = ... → 60 秒(**非最左列單獨用 = 索引失效**)
鐵律: 最左列必須是最高頻查詢欄位;非最左列單獨查詢不走索引。
ORDER BY 小資料量明顯快於非聚集;大資料量 (>10萬) 差異縮小。優化器需將 WHERE 條件轉為 **SARG 形式** 才能利用索引:
欄位 運算子 常數/變數
常數/變數 運算子 欄位
-- 範例
name = '張三'
price > 5000
5000 < price
name = '張三' AND price > 5000
非 SARG 形式 → 全表掃描:
YEAR(order_date) = 2024 → 改 order_date >= '2024-01-01' AND order_date < '2025-01-01'price * 1.1 > 5000 → 改 price > 5000/1.1varchar_col = 123 → 索引失效。SQL Server 優化器會自動重排 AND 條件順序,**無需手動調整 WHERE 順序**,但必須寫成 SARG 形式。
索引設計核心:**聚集索引給範圍查詢高頻欄位、非聚集給高選擇性點查欄位、複合索引嚴守最左前綴、所有條件寫成 SARG 形式**。誤區源於「主鍵即聚集」與「建索引必提速」直覺,實測數據證明:正確的聚集索引選擇能帶來**百倍效能差距**。