JOIN、EXISTS、APPLY、CTE、臨時表,減少重複掃描。WHERE CONVERT(DATE, CreateTime) = '2024-01-15'WHERE CreateTime >= '2024-01-15' AND CreateTime < '2024-01-16'(SARGable,可用索引)。UNION ALL 或 IN。NOT IN 遇 NULL 返回空集,邏輯陷阱;EXISTS 半連接,匹配即停止,性能更穩定。WHERE Salary * 12 > 25000WHERE Salary > 25000 / 12 或建計算列 + 索引。WHERE Status IN (1,2,3) 優化器易轉為索引查找。WHERE Status IS NOT NULL。(A,B,C),查詢必須包含 A 才能用到索引。UNION 會去重(Sort/Distinct),UNION ALL 直接合並,無去重開銷。WHERE EmpNo = '123'(EmpNo 為 INT)→ CONVERT(VARCHAR, EmpNo) = '123' 導致掃描WHERE EmpNo = 123 或參數化強類型。WHERE Status < 1 OR Status > 1(極少數值時)或全表掃描不可避免則接受。(GroupCol, AggCol)。LIKE 'ABC%' 走索引,LIKE '%ABC'、LIKE '%ABC%' 不走。全文搜索用全文索引/ES。WHERE Zip LIKE '98___' → WHERE Zip BETWEEN '98000' AND '98999' 走索引。AUTO_UPDATE_STATISTICS ON,大表啟用 AUTO_UPDATE_STATISTICS_ASYNC ON 避免查詢等待。UPDATE STATISTICS TableName WITH FULLSCAN(維護窗口)。sys.dm_db_index_physical_stats 檢測,>30% 重建,5-30% 重組。FILLFACTOR = 80-90 減少頁分裂。| 算子 | 含義 | 優化方向 |
|---|---|---|
| Table Scan / Clustered Index Scan | 全表掃描 | 加索引、縮小範圍、分區剪枝 |
| Index Seek | 索引查找(理想) | 覆蓋索引避免 Key Lookup |
| Key Lookup (Bookmark Lookup) | 回表查詢非索引列 | INCLUDE 列建覆蓋索引 |
| Hash Match / Merge Join | 大表連接 | 確保連接鍵有索引、統計信息新鮮 |
| Sort / Distinct | 排序/去重 | 索引順序滿足 ORDER BY、UNION ALL 替代 UNION |
| Spool / Eager Spool | 臨時存儲中間結果 | 重寫查詢、拆分邏輯、優化 TempDB |