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

SQL Server 索引與查詢執行計劃實戰:聚集 vs 非聚集索引選擇策略

     編輯:關於SqlServer

前言

索引是資料庫效能調優的核心,但「建了索引就會用上」是危險迷思。本文透過實際執行計劃對比,揭示 SQL Server 為何有時放棄聚集索引而選擇非聚集索引,以及強制索引的真實影響。

實戰場景:Sales.Orders 表

假設表擁有主鍵 PK_Orders(聚集索引,鍵值 orderid)與非聚集索引 idx_nc_custid(鍵值 custid)。

1. 預設行為:查單欄 vs 查全表

USE TSQL2012
GO
SELECT orderid FROM Sales.Orders      -- 單欄
SELECT * FROM Sales.Orders            -- 全欄

觀察:

  • SELECT orderid:優化器選擇非聚集索引掃描(覆蓋索引),成本極低。
  • SELECT *:優化器選擇聚集索引掃描(需回表取所有列),成本約 3 倍。

即使查詢主鍵欄位無 WHERE 條件,優化器也傾向用較窄的非聚集索引而非聚集索引。

2. 強制使用聚集索引

SELECT orderid FROM Sales.Orders WITH(INDEX(PK_Orders))
SELECT * FROM Sales.Orders WITH(INDEX(PK_Orders))

強制後,單欄查詢成本大幅上升(掃描較寬聚集索引),全欄查詢成本持平。結論:單欄查詢勿強制聚集索引。

3. 強制使用非聚集索引

SELECT orderid FROM Sales.Orders WITH(INDEX(idx_nc_custid))
SELECT * FROM Sales.Orders WITH(INDEX(idx_nc_custid))

單欄查詢成本極低(覆蓋索引);全欄查詢觸發鍵查找,成本暴增。非聚集索引不適合 SELECT * 無過濾條件場景。

核心洞見

  1. 覆蓋索引為王: 查詢欄位若全部包含在非聚集索引鍵/包含欄中,優化器極偏好使用它。
  2. 聚集索引非萬能: 窄非聚集索引掃描成本常低於寬聚集索引掃描。
  3. SELECT * 反模式: 強迫回表或掃描聚集索引,效能殺手。
  4. 執行計劃看「估算行數」與「實際行數」: 偏離大時統計資訊過期,需 UPDATE STATISTICS。

調優建議

  • 優先設計覆蓋索引滿足高頻查詢,而非盲目建聚集索引。
  • 生產環境嚴禁 SELECT *,明確列出所需欄位。
  • 強制索引僅作臨時驗證手段,長期方案應優化統計資訊、重寫查詢或調整索引設計。
  • 定期檢視 sys.dm_db_index_usage_stats 識別未用/低效索引並清理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved