高性能 SQL 是系統吞吐量的基石。本文匯總 34 條經過生產驗證的優化鐵律,涵蓋 優化器行為利用、索引設計、WHERE 寫法重構、連接優化、聚合排序、臨時對象、事務控制、數據類型 八大維度,每條附反模式→最佳實踐對比與核心原理,可直接作為代碼審查清單。
UPDATE STATISTICS / ANALYZE TABLE)。INCLUDE 選列表列,讓非聚集索引直接滿足查詢。col IS NULL → 設默認值 0/-1 查 col=0(NULL 不入普通索引)。col != val → 改寫為 col < val OR col > val 或範圍查詢(不等值不走索引)。WHERE a=1 OR b=2 → UNION ALL 合併(OR 導致全掃,除非兩側各有索引且優化器支持 Index Merge)。IN (列表) 連續值 → BETWEEN;列表過長(>100)考慮臨時表 JOIN。LIKE '%abc' → 全文索引 / 反向存儲列 / LIKE 'abc%'(前導通配符殺死索引)。col/2=100→col=200;SUBSTRING(col,1,3)='abc'→col LIKE 'abc%';DATEDIFF(day,dt,'2024')=0→dt>='2024-01-01' AND dt<'2025-01-01'。OPTION (RECOMPILE);複雜語句用動態 SQL 構建具體值計劃。col=123 → 強制 col='123';數字列比字符同理。IN (subquery) → EXISTS (subquery):半連接,滿足即返回,不產生中間結果集。NOT IN (subquery) → NOT EXISTS / LEFT JOIN ... WHERE IS NULL:NOT IN 含 NULL 邏輯陷阱且全掃。DISTINCT → EXISTS / 分組去重:DISTINCT 觸發排序,大結果集極慢。UNION → UNION ALL(業務允許重複時):省去排序去重,節省 SORT_AREA_SIZE 內存。OR 條件列有索引 → UNION ALL 分支查詢合併(各分支走各自索引)。GROUP BY 隱式排序 → ORDER BY NULL 禁止排序(MySQL)。ORDER BY 無索引 → 建複合索引 (where_eq_col, order_col) 實現索引有序掃描。OFFSET 100000 LIMIT 20 → 鍵集分頁 WHERE pk > last_seen_pk ORDER BY pk LIMIT 20 或 ROW_NUMBER() 篩選主鍵回表。COUNT(1)/COUNT(pk) → COUNT(*):引擎對 COUNT(*) 有特殊優化(MyISAM 直接讀元數據,InnoDB 掃描最小二級索引)。COUNT(col) ≠ COUNT(*):前者統計非 NULL 行,後者統計總行數,語義不同勿混用。tempdb 系統表鎖定。SELECT INTO(最小日誌)+ 後建索引。SET NOCOUNT ON/OFF:抑制 DONE_IN_PROC 消息,減少網絡包。EXPLAIN 對比、邏輯讀對比、實際耗時對比(預熱後多次取中位數)。內化這 34 條,SQL 性能問題將在代碼評審階段被 90% 以上攔截。