MySQL 查詢優化器對 WHERE 子句執行多層次優化。本文系統整理官方文檔優化規則:括號消除、常數傳播、死碼消除、索引統計採樣、常數表識別、連接順序枚舉、臨時表觸發條件、ICP/MRR 等進階特性,並給出典型高效查詢模式。
| 優化規則 | 轉換示例 |
|---|---|
| 消除冗餘括號 | ((a AND b) AND c) → (a AND b AND c) |
| 常數傳播/摺疊 | (a < b AND b = c AND a = 5) → (b > 5 AND b = c AND a = 5) |
| 消除常數條件 | (B>=5 AND B=5) OR (B=6 AND 5=5) → B=5 OR B=6 |
| 常數表達式單次計算 | 索引條件中的常數表達式只算一次 |
| 無 WHERE 的 COUNT(*) 直接讀表統計 | MyISAM 瞬時返回;InnoDB 掃描主鍵 |
| 早期檢測不可能條件 | WHERE 1=0 直接返回空集 |
| HAVING 無 GROUP BY 時併入 WHERE | 等價轉換簡化執行計劃 |
Using index)以下情況視為「常數表」,優化器優先讀取並作為連接駕駛表:
-- 典型常數表 SELECT * FROM t WHERE primary_key = 1; SELECT * FROM t1, t2 WHERE t1.pk = 1 AND t2.pk = t1.id;
SQL_SMALL_RESULT 提示使用內存臨時表| 場景 | 原因 |
|---|---|
| ORDER BY 與 GROUP BY 列不一致 | 需兩階段排序 |
| ORDER BY/GROUP BY 包含非駕駛表列 | 需收集所有行再排序 |
| DISTINCT + ORDER BY | 轉為 GROUP BY 所有列 |
-- 1. 單表統計(極快) SELECT COUNT(*) FROM tbl; SELECT MIN(key), MAX(key) FROM tbl; SELECT MAX(key2) FROM tbl WHERE key1 = const; -- 2. 索引覆蓋 + LIMIT(極快) SELECT * FROM tbl ORDER BY key1, key2 LIMIT 10; SELECT * FROM tbl ORDER BY key1 DESC, key2 DESC LIMIT 10; -- 3. 僅走索引樹(覆蓋索引) SELECT key1, key2 FROM tbl WHERE key1 = val; SELECT COUNT(*) FROM tbl WHERE key1 = v1 AND key2 = v2; SELECT key2 FROM tbl GROUP BY key1; -- 4. 索引順序掃描避免 filesort SELECT * FROM tbl ORDER BY key1, key2; SELECT * FROM tbl ORDER BY key1 DESC, key2 DESC;
每行輸出前評估 HAVING,不匹配則跳過,不影響索引選擇。