查詢執行計畫是 SQL Server 效能調校的核心地圖。本文從圖形化計畫解讀、運算子分類 (Scan/Seek)、三大 Join 策略、SET STATISTICS PROFILE 實際執行分析、統計資訊機制、視圖優化特性,系統建構完整的執行計畫分析能力。
一、圖形化執行計畫核心解讀
點選 SSMS 工具列「顯示估計的執行計畫」 (Ctrl+L) 或「包含實際的執行計畫」 (Ctrl+M)。
三大關鍵資訊
- 成本百分比:右側運算子通常成本最高 (資料流向:右 → 左)。
- 資料流量 (線條粗細):粗 = 列數多,細 = 列數少。
- 運算子類型:識別 Scan/Seek/Join 類型。
二、資料存取運算子層級
| 運算子 | 描述 | 效能 | 優化方向 |
| Table Scan | 掃描整張堆疊表 | 最差 | 建立叢集索引 |
| Clustered Index Scan | 掃描整張叢集索引 (等同 Table Scan) | 差 | 建立非叢集索引支援 Seek |
| Index Scan | 掃描非叢集索引部分頁面 | 中 | 縮小掃描範圍或改為 Seek |
| Index Seek | 透過非叢集索引定位再回叢集索引 (Key Lookup) | 良 | 建立覆蓋索引移除 Lookup |
| Clustered Index Seek | 直接透過叢集索引定位 | 最佳 | 維持叢集索引鍵單調遞增 |
原則: 發現高成本 Scan → 評估建立索引;但低選擇性欄位 (如性別 0/1) 建索引無效,需分區/分表。
三、三大 Join 策略深度解析
1. Nested Loops Join (巢狀迴圈)
- 適用:外部輸入小、內部輸入大且有索引。
- 邏輯:
foreach outer_row: foreach inner_row: if match output
- 變體:Naive (全掃描)、Index (索引尋找)、Temporary Index (臨時索引)。
- 小交易/OLTP 最佳;大查詢通常非最優。
2. Merge Join (合併聯接)
- 適用:兩輸入皆大且已排序 (或可透過索引取得排序)。
- 前提:Join 鍵為等值條件 (ON 子句)。
- 流程:雙指標同步推進,相等輸出,較小者前進。
- 多對多需暫存表 (效能損),建立唯一索引可避免。
- 大量已排序資料最快;需額外排序則成本高。
3. Hash Join (雜湊聯接)
- 適用:大量、未排序、無索引輸入 (如中間結果集)。
- 階段:Build (小表建雜湊表) → Probe (大表探測匹配)。
- 類型:In-memory、Grace (分區溢寫磁碟)、Recursive (多層分區)。
- 動態角色互換:若優化器誤判大小,執行中自動互換 Build/Probe。
- 支援所有 Join 類型 + Group By/Distinct。
Join 策略選擇決策樹
IF 兩表皆小 OR 一表極小有索引 → Nested Loops
ELSE IF 兩表大且已排序 (索引/排序) → Merge Join
ELSE → Hash Join
四、SET STATISTICS PROFILE 實際執行分析
SET STATISTICS PROFILE ON;
SELECT ... FROM ... WHERE ...;
-- 結果兩張表:查詢結果 + 執行過程表格
執行過程表格關鍵欄位
| 欄位 | 含義 |
| Rows | 實際產生列數 (真實值) |
| Executes | 該步驟執行次數 (真實值) |
| StmtText | 步驟描述 (運算子、物件、條件) |
| EstimateRows | 預估列數 |
自內而外閱讀法
- 最內層 (最後幾行) = 資料存取 (Scan/Seek)。
- 中間層 = Join/彙總/計算。
- 最外層 (第 1 行) = 最終 SELECT 輸出。
五、統計資訊:優化器的決策依據
查看統計資訊
DBCC SHOW_STATISTICS ('Products', 'IX_CategoryID');
三區塊結構
- 標頭:名稱、更新時間、列數、取樣列數、Steps (直方圖階數)、Density (選擇性)、平均鍵長、String Index。
- 密度向量:各欄位前綴組合的 Density (越小選擇性越高,<0.1 為佳)。
- 直方圖:最多 200 階,每階
RANGE_HI_KEY、RANGE_ROWS、EQ_ROWS、DISTINCT_RANGE_ROWS、AVG_RANGE_ROWS。
統計資訊自動維護
AUTO_CREATE_STATISTICS ON (預設):查詢用到無索引欄位自動建立。
AUTO_UPDATE_STATISTICS ON (預設):約 20% 資料變更觸發更新 (小表全掃描)。
AUTO_UPDATE_STATISTICS_ASYNC:非同步更新,查詢不等待但可能用舊統計資訊。
統計資訊過期導致計畫偏差
- 實際 Rows 與 EstimateRows 差距大 (超過 10 倍) → 考慮
UPDATE STATISTICS 或重建索引。
- 重建索引會同步更新統計資訊 (全掃描),常能解決突發效能問題。
六、視圖優化特性
- 視圖定義本身不執行,優化器會將視圖定義「內展」至外部查詢。
- 同一視圖,不同
WHERE 條件 → 完全不同執行計畫。
- 範例:
OrdersView 直接查 → Clustered Index Scan;加 WHERE OrderId=1 → Clustered Index Seek。
- 建議:視圖定義保持簡單,依實際查詢模式建立索引,而非針對視圖定義優化。
推薦參考文獻
精通執行計畫分析,能從「猜測調優」轉為「精準診斷」,是資料庫效能工程師的核心競爭力。
- 上一篇文章: SQL Server 判斷字串是否包含數字與英文字母:PATINDEX 實戰技巧
- 下一篇文章: SQL Server 自訂函數 vs 預存程序:核心差異、限制比較與適用場景完整指南
Copyright ©
程式碼之家 All Rights Reserved