面對萬張表的索引優化,人工逐表分析不切實際。本文揭露一套基於執行計畫 XML 解析 → 謂詞統計 → 索引組合生成 → 覆蓋/合併/剔除決策 → 自動化部署的自動化索引優化工具設計全貌,含 XSD 結構映射、關鍵演算法、風險控制與工程化落地細節。
sys.dm_exec_cached_plans + sys.dm_exec_query_plan + sys.dm_exec_query_statsIndexAnalytics,表結構:PlanID, QueryHash, PlanXML, ExecCount, TotalCPU, TotalDuration, TableStatsSnapshotStmtSimple 缺失、Adhoc 計畫 (若 usecounts=1)、系統查詢、DDLXSD 位置:schemas.microsoft.com/sqlserver/2004/07/showplan/sql2008/showplanxml.xsd
| 目標資訊 | XML 節點路徑 / 邏輯 | 備註 |
|---|---|---|
| 查詢文本 | /Batch/Statements/StmtSimple/@StatementText | 可關聯 sys.dm_exec_sql_text |
| 輸出欄位 (SELECT) | //OutputList/ColumnReference → @Database,@Schema,@Table,@Column | 首個 OutputList 為最終輸出 |
| WHERE 謂詞 | //Where//ScalarOperator/ScalarString 或 //SeekKeys/SeekKey/ColumnReference | 含參數化形式 @1、常數 Const |
| JOIN 謂詞 | //RelOp[@LogicalOp='Inner Join' or 'Left Outer Join']//Compare/ColumnReference | 成對出現,一側為參數/常數則為 WHERE |
| GROUP BY / ORDER BY | //GroupBy//ColumnReference, //OrderBy//ColumnReference | |
| 存取路徑 | //RelOp[@PhysicalOp='Index Seek/Scan']//Object/@Table, @Index, @IndexKind | 驗證現有索引使用情況 |
| 缺失索引提示 | //MissingIndexes/MissingIndexGroup/MissingIndex/@Table, @EqualityColumns, @InequalityColumns, @IncludedColumns | 優化器建議,參考價值高 |
對每張表,聚合所有計畫中的欄位引用:
TableColumnStats:
TableName, ColumnName,
SelectCount, -- 出現在 SELECT/OUTPUT
JoinCount, -- 出現在 JOIN ON
WhereCount, -- 出現在 WHERE/SEEK
GroupByCount,
OrderByCount,
ExecFrequency, -- 加權:Sum(ExecCount * Weight)
BusinessWeight -- 業務標記:核心交易=10, 報表=5, 管理=1
JoinCount+WhereCount > 0 的欄位組合 (單欄 + 常見多欄組合)SelectCount > 0 且 DataType NOT IN (LOB, MAX) 且 修改頻率低 (從 sys.dm_db_index_usage_stats.user_updates 估算)Score = Σ(謂詞頻率 * 業務權重 * 選擇性增益)| 規則 | 邏輯 | 動作 |
|---|---|---|
| 主鍵覆蓋 | 候選索引鍵前綴 = PK | 剔除 (PK 已隱含) |
| 完全覆蓋 | IdxA 鍵+INCLUDE ⊇ IdxB 鍵+INCLUDE | 保留 IdxA,剔除 IdxB |
| 部分重疊合併 | IdxA=(A,B) INCL(C), IdxB=(A,B) INCL(D) | 合併為 (A,B) INCL(C,D) — 若 C/D 修改頻率低 |
| 順序差異 | IdxA=(A,B), IdxB=(B,A) | 保留高分者,或視查詢模式保留雙方 |
| 低分剔除 | Score < 閾值 (如總分 1%) | 標記人工審核 |
CREATE INDEX ... WITH (ONLINE=ON, MAXDOP=4, DATA_COMPRESSION=PAGE) 腳本ONLINE=ON 避免鎖表,失敗自動回滾sys.dm_db_index_usage_stats,未被使用者標記清理Optimize for Ad hoc Workloads,避免單用計畫污染快取QueryHash 聚合而非 PlanHandleColumnReference 缺 @Database/@Schema/@Table 者為系統表/變數,必須剔除索引自動優化是「資料驅動運維」的典型場景。技術路徑已清晰,關鍵在於治理流程、可解釋性、漸進式信任建立。將 DBA 從繁瑣分析解放,轉型為「架構決策者、風險把關者」,才是工具的終極價值。