EXPLAIN SELECT ... FROM ... WHERE ...;
-- 或
EXPLAIN EXTENDED SELECT ...; -- 後接 SHOW WARNINGS 看優化器重寫
可視化工具:mk-visual-explain 生成樹形執行計劃。
| 列名 | 含義 | 關鍵關注點 |
|---|---|---|
id | 查詢序號,標識執行順序 | 從大到小執行;子查詢 id 較大,先執行 |
select_type | 查詢類型 | SIMPLE、PRIMARY、UNION、SUBQUERY、DERIVED 等 |
table | 訪問的表 | 衍生表顯示 <derivedN> |
type | 訪問類型(最關鍵) | system > const > eq_ref > ref > range > index > ALL |
possible_keys | 可能用到的索引 | 為 NULL 表示無索引可用 |
key | 實際使用的索引 | 可用 FORCE/USE/IGNORE INDEX 干預 |
key_len | 索引長度(字節) | 越短越好;判斷組合索引用了幾列 |
ref | 與索引比較的列/常量 | const 表示常量 |
rows | 預估掃描行數 | 越小越好;結合 filtered 估算實際返回 |
Extra | 額外信息 | Using filesort、Using temporary 為紅旗 |
IS NULL。>, >=, <, <=, BETWEEN, IN)。Using index:覆蓋索引,只讀索引不回表,**極佳**。Using where:WHERE 過濾,配合 ALL/index 需警惕。Using filesort:需額外排序,**通常需優化**(建索引消除)。Using temporary:創建臨時表,**通常需優化**(調整 GROUP BY/ORDER BY 列順序)。Range checked for each record:無理想索引,極慢。SELECT author_id FROM article
WHERE category_id = 1 AND comments > 1
ORDER BY views DESC LIMIT 1;
表結構:id PK, author_id, category_id, views, comments, title, content,初始僅有主鍵。
EXPLAIN ...
-- type: ALL, key: NULL, Extra: Using where; Using filesort
(category_id, comments, views)ALTER TABLE article ADD INDEX x (category_id, comments, views);
-- type: range, key: x, Extra: Using where; Using filesort
仍有 filesort。原因:comments > 1 是範圍條件,B+ 樹組合索引中範圍列後的列(views)無法用於排序。
(category_id, views)ALTER TABLE article ADD INDEX y (category_id, views);
-- 優化器可能仍選舊索引 x,需強制
EXPLAIN SELECT ... FORCE INDEX (y) ...;
-- type: ref, key: y, Extra: Using where ✅ filesort 消失
或刪除索引 x 讓優化器自動選 y。
EXPLAIN EXTENDED + SHOW WARNINGS 查看優化器重寫後的 SQL。rows × filtered/100 估算實際參與 JOIN 的行數。ref/eq_ref。JOIN 或利用 unique_subquery/index_subquery。EXPLAIN 是 SQL 調優的「聽診器」。核心目標:讓 type 至少達到 range,最好 ref/eq_ref/const;Extra 無 filesort/temporary。結合組合索引設計原則,大多數慢查詢可通過調整索引順序、增加覆蓋列、消除範圍列後的排序列來解決。