優化的起點不在索引、不在查詢,而在範式化與反範式化的平衡藝術。優秀的邏輯設計帶來的連鎖收益:
黃金法則: 以第三範式(3NF)為基線,針對高頻連接查詢、報表匯總場景有選擇地反範式化(增加冗餘列、物化視圖、索引視圖),而非全盤反範式化。外鍵列必須與主鍵數據類型、長度、校驗規則完全一致,避免隱式轉換導致索引失效。
WHERE 子句中的每一列都是索引候選者。對於 WHERE col1 = ?,有效索引模式為:
(col1)(col1, col2, ...) 且 col1 為首列反例: (col2, col1) 無法優化上述查詢。
單列/雙列窄索引:每頁容納更多條目、B+樹層級更少、維護開銷更低。複合索引統計信息僅包含首列直方圖+全列密度,若首列選擇性差,優化器傾向放棄索引。
| 唯一值比例 | 推薦索引類型 | 說明 |
|---|---|---|
| > 50% (如 5000/10000) | 非聚簇索引 | 高選擇性,精準定位 |
| 1% - 50% | 視查詢模式定 | 範圍查詢考慮聚簇,點查詢非聚簇 |
| < 1% (如 20/10000) | 聚簇索引 | 低選擇性列適合聚簇,掃描少量頁即可 |
| 極低 (如 3/10000) | 不建索引 | 掃描全表更優,索引維護成本>收益 |
| 場景 | 推薦 | 理由 |
|---|---|---|
| 範圍查詢 (BETWEEN, >, <, >=, <=) | 聚簇 | 物理順序=邏輯順序,掃描連續頁 |
| 大結果集返回 (如 >10%表行數) | 聚簇 | 避免書籤查找,直接讀取數據頁 |
| 高頻點查詢、唯一鍵、主鍵 | 聚簇 (主鍵默認) | 單行定位最快 |
| 高並發 INSERT 尾部熱點 (IDENTITY/SEQUENCE) | 避免聚簇 | 最後一頁鎖爭用,改用非聚簇+分區/In-Memory OLTP |
| ORDER BY / GROUP BY 列 | 聚簇或覆蓋索引 | 利用有序性避免排序 |
| 高基數列 (如 PartID, EmployeeID) | 非聚簇 | 精準定位,覆蓋索引可避免回表 |
avg_fragmentation_in_percent > 30% → REBUILD (ONLINE=ON);5%-30% → REORGANIZEAUTO_UPDATE_STATISTICS,大表配合 AUTO_UPDATE_STATISTICS_ASYNC,關鍵表手動 UPDATE STATISTICS ... WITH FULLSCANsys.dm_db_missing_index_details / sys.dm_db_index_usage_stats (user_seeks+scans+lookups=0 為候選刪除)SELECT * FROM table 全表掃描TOP / OFFSET-FETCH 限制結果集,減少網絡I/O與客戶端內存壓力WHERE col = ?、WHERE col > ?、WHERE col IN (?,?);避免 WHERE func(col) = ?、WHERE col + 1 = ?、WHERE col LIKE '%abc' 導致索引失效索引 (au_lname, au_fname):
WHERE au_lname = 'White' — 首列匹配,索引求值WHERE au_lname = 'White' AND au_fname = 'Johnson' — 全匹配,最優WHERE au_fname = 'Johnson' — 非首列,索引掃描甚至放棄INCLUDE 非鍵列滿足 SELECT 列表,實現「索引即數據」,零回表WHERE status = 1 只索引活躍數據,體積小、維護快MAXDOP 設置為 NUMA節點核數 (通常 ≤8);Cost Threshold for Parallelism 提至 50Perform Volume Maintenance Tasks,加速數據文件擴展性能優化無終點,只有「當前瓶頸」與「下一個瓶頸」。建立基線指標 → 壓力測試 → 瓶頸定位 → 驗證優化 → 固化最佳實踐的閉環,比任何單點技巧更有價值。