EXPLAIN 是 MySQL 查詢優化器的「X 光機」,能揭示執行計劃、訪問類型、索引使用情況與潛在效能隱患。本文系統講解所有輸出列含義,並通過單表範圍查詢、左/右/內連接、三表連接四大實戰案例,演示「看計劃 → 找問題 → 加索引 → 驗證」的標準優化閉環。
| 列名 | 含義 | 關鍵值解讀 |
|---|---|---|
| id | 查詢序號 | 值大優先執行;相同 id 從上到下 |
| select_type | 查詢類型 | SIMPLE/PRIMARY/UNION/SUBQUERY/DEPENDENT UNION/DEPENDENT SUBQUERY/DERIVED/UNCACHEABLE... |
| table | 訪問的表 | 衍生表顯示 |
| type | 訪問類型(核心) | system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL(由優到劣) |
| possible_keys | 理論可用索引 | NULL 表示無索引可用 |
| key | 實際使用索引 | NULL 表示未用索引;可用 USE/FORCE/IGNORE INDEX 干預 |
| key_len | 索引長度(字節) | 越短越好;可推斷聯合索引用了幾列 |
| ref | 索引比較值來源 | const/列名/函數 |
| rows | 預估掃描行數 | 越小越好;統計信息不準時會偏離 |
| Extra | 額外信息 | Using filesort(外部排序)、Using temporary(臨時表)、Using index(覆蓋索引)、Using where(WHERE 過濾) |
表 article(category_id, comments, views),查詢:
SELECT author_id FROM article
WHERE category_id=1 AND comments>1 ORDER BY views DESC LIMIT 1;
type: ALL, key: NULL, rows: 3, Extra: Using where; Using filesort
ALTER TABLE article ADD INDEX x (category_id, comments, views);
type: range, key: x, key_len: 8, Extra: Using where; Using filesort
原因: comments>1 是範圍條件,導致其後 views 索引列失效(B+Tree 最左前綴原理)。
DROP INDEX x ON article;
ALTER TABLE article ADD INDEX y (category_id, views);
type: ref, key: y, key_len: 4, Extra: Using where
範圍列放最後,等值列前置,排序列納入索引實現「索引下推 + 避免 filesort」。
三表 class(card)、book(card)、phone(card),各 2 萬行。
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card=book.card;
-- 初始:雙 ALL
-- 加 book(card) 索引 → book 變 ref,rows 20000→1000
-- 加 class(card) 索引 → 無改善(左表必須全掃)
EXPLAIN SELECT * FROM class RIGHT JOIN book ON class.card=book.card;
-- 加 class(card) 索引 → class 變 ref
-- 加 book(card) 索引 → 無改善
EXPLAIN SELECT * FROM class INNER JOIN book ON class.card=book.card;
-- 加 book(card) 或 class(card) 均能讓非驅動表變 ref
EXPLAIN SELECT * FROM class
LEFT JOIN book ON class.card=book.card
LEFT JOIN phone ON book.card=phone.card;
-- 給 book(card)、phone(card) 加索引 → 後兩表均為 ref,rows 大幅下降
EXPLAIN 不會說謊,但需要懂得如何提問與解讀。練就「一眼看穿執行計劃」的功力,優化從玄學變科學。