SQL 優化無銀彈,但有高概率生效的「軍規」。本文提煉 30 條核心優化法則,涵蓋索引設計、查詢重寫、架構協同,助你系統化提升查詢性能。
索引與訪問路徑(1-7)
- 避免全表掃描:WHERE/ORDER BY/JOIN 列優先建索引
- 拒絕 != / <>:導致索引失效,改用
IN/NOT IN 或業務邏輯規避
- 拒絕 IS NULL 判斷:設置默認值 0/空串,查
=0 替代 IS NULL
- 拒絕 OR 連接條件:改用
UNION ALL 分開查詢合併結果
- 拒絕 LIKE '%keyword%':前導通配符殺死索引,改用全文索引或搜索引擎
- 慎用 IN / NOT IN:連續值用
BETWEEN,子查詢用 EXISTS
- 參數化查詢索引失效:變量值編譯時未知,優化器無法選擇索引,用
FORCE INDEX 或應用層構造常量 SQL
表達式與函數陷阱(8-11)
- 拒絕列上算術運算:
WHERE num/2=100 → WHERE num=200
- 拒絕列上函數調用:
SUBSTRING(name,1,3)='abc' → name LIKE 'abc%';DATEDIFF(day,dt,'2024-01-01')=0 → dt>='2024-01-01' AND dt<'2024-01-02'
- WHERE 左側禁函數/運算:破壞索引使用
- 複合索引最左前綴:必須包含第一列,順序與索引定義一致
查詢重寫技巧(12-18)
- 無意義查詢改 DDL:
SELECT ... WHERE 1=0 → CREATE TABLE ... LIKE ...
- EXISTS 替代 IN:
IN (SELECT ...) → EXISTS (SELECT 1 FROM ... WHERE ...)
- 低區分度列索引無效:如性別、狀態枚舉,優化器放棄索引
- 索引不是越多越好:單表 ≤6,寫入開銷與鎖競爭隨索引數線性增長
- 避免更新聚簇索引列:主鍵修改導致頁分裂、數據重排,極其昂貴
- 優先數字類型:字符串比較逐字符,數字一次比較,性能差 10 倍+
- VARCHAR 替代 CHAR:變長節省空間,掃描更少頁(UTF8 下 CHAR 也變長)
臨時表與游標(19-27)
- 表變量替代臨時表:僅主鍵索引,適合小數據集
- 減少臨時表創建銷毀:消耗系統表資源
- 大量數據用 SELECT INTO:避免大量 Binlog,速度快;小數據
CREATE + INSERT
- 存儲過程末尾顯式清理:
TRUNCATE → DROP,避免系統表長鎖定
- 避免游標:>1 萬行必改集合操作
- 優先集合思維:SQL 本質是集合運算,游標是退化的行式處理
- 小結果集 FAST_FORWARD 游標可接受:多表關聯取匯總場景
工程規範(28-30)
- 存儲過程 SET NOCOUNT ON:減少客戶端網絡往返
- 拒絕大結果集直輸客戶端:分頁、流式、異步導出
- 拒絕大事務:拆分小批次,提升並發吞吐
驗證清單
- 每條慢 SQL 必過
EXPLAIN 驗證 type、key、rows、Extra
- 上線前基準測試對比 QPS/RT/P99
- 建立 SQL Review 機制,攔截反模式
30 條軍規非絕對真理,但覆蓋 90% 以上常見性能坑。內化為肌肉記憶,寫出高性能 SQL 成為本能。