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

SQL Server 索引架構深度解析:叢集 vs 非叢集、何時使用、決策對照表

     編輯:關於SqlServer

一、索引概念:特殊的「目錄」

叢集索引 = 字典正文

漢語字典正文**按拼音排序**,正文本身就是目錄。查「安」字,自然翻到前面;查「張」字,翻到後面。**資料物理順序 = 索引邏輯順序**。一張表**只能有一個**叢集索引,因為資料只能有一種物理排序。

非叢集索引 = 部首檢字表

不認識字音時,查「部首目錄」→ 找到頁碼 → 翻到正文該頁。目錄與正文分離,**目錄儲存 (鍵值, 頁碼/書籤)**。**一張表可建多個非叢集索引**(最多 999 個,含 XML/空間索引)。

二、叢集 vs 非叢集 關鍵差異

特性叢集索引非叢集索引
資料儲存葉層 = 完整資料列葉層 = 索引鍵 + 書籤 (RID 或叢集鍵)
每表數量1最多 999
預設建立主鍵預設建叢集唯一約束預設建非叢集
範圍查詢極快(連續頁)需書籤查找,較慢
插入/更新可能造成頁分裂需同步維護所有非叢集索引
覆蓋索引天然覆蓋所有欄位需 INCLUDE 欄位才能覆蓋

三、何時使用叢集 / 非叢集 索引(決策對照表)

動作/場景叢集索引非叢集索引
欄位經常 GROUP BY / ORDER BY✅ 適合✅ 適合
範圍查詢 (BETWEEN, >, <)✅ 適合❌ 不適合
極少唯一值 (如性別、狀態)❌ 不適合❌ 不適合
少量唯一值 (如部門代碼)✅ 適合❌ 不適合
大量唯一值 (如身分證、流水號)❌ 不適合✅ 適合
頻繁 UPDATE 的欄位❌ 不適合✅ 適合
外鍵欄位✅ 適合✅ 適合
主鍵欄位✅ 適合✅ 適合
> 💡 **核心原則**:叢集索引給「範圍查詢、排序、分組」的高選擇性欄位;非叢集索引給「精確查找、連接、覆蓋」的高基數欄位。

四、進階主題

覆蓋索引

非叢集索引葉層包含查詢所需**所有欄位**,查詢無需回表(Key Lookup / RID Lookup)。

CREATE NONCLUSTERED INDEX IX_Orders_CustDate_Cover
ON Orders (CustomerID, OrderDate)
INCLUDE (TotalAmount, Status);  -- 非鍵欄位只存在葉層,不參與排序

篩選索引

針對特定子集建立索引,縮小索引體積、減少維護成本。

CREATE NONCLUSTERED INDEX IX_Orders_Active
ON Orders (OrderDate)
WHERE Status = 'Active';  -- 只索引有效訂單

叢集索引鍵選擇原則

  1. 窄:越窄越好(INT < BIGINT < CHAR(36)),因非叢集索引葉層會複製叢集鍵作為書籤。
  2. 唯一:避免唯一化器(Uniquifier)額外 4 位元組開銷。
  3. 遞增:IDENTITY、NEWSEQUENTIALID() 減少頁分裂、碎片。
  4. 靜態:極少更新,避免非叢集索引書籤同步修改。

堆積表

無叢集索引的表稱為堆積。資料無序儲存,非叢集索引書籤為 RID (File:Page:Slot)。適合:純載入暫存表、日誌表、極少查詢的歸檔表。

五、索引維護與監控

  • 碎片整理:sys.dm_db_index_physical_stats 檢測 avg_fragmentation_in_percent > 30% → REBUILD;5-30% → REORGANIZE。
  • 缺失索引建議:sys.dm_db_missing_index_* DMV 分析優化器記錄的缺失索引請求。
  • 未使用索引:sys.dm_db_index_usage_stats 找出 user_seeks + user_scans + user_lookups = 0 的索引,評估刪除。
  • 統計資料:自動更新統計資料 (AUTO_UPDATE_STATISTICS ON) + 定期 UPDATE STATISTICS 全掃描。

六、快速決策流程圖

新增索引前問自己:
1. 查詢模式?範圍/排序 → 叢集;精確/連接 → 非叢集
2. 欄位基數?高 → 非叢集;中低但範圍查 → 叢集
3. 更新頻率?高 → 避免叢集,謹慎非叢集
4. 是否覆蓋?加 INCLUDE 消除 Key Lookup
5. 是否可篩選?WHERE 固定值 → FILTERED INDEX
6. 叢集鍵是否窄/唯一/遞增/靜態?否 → 重新設計
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved