基本語法
EXPLAIN [EXTENDED] SELECT ... FROM ... WHERE ...
EXTENDED:配合 SHOW WARNINGS 查看優化後查詢重寫資訊。
- 僅支援
SELECT,分析 UPDATE/DELETE 時將條件轉為 SELECT 即可。
視覺化工具 mk-visual-explain
# 管道模式
mysql -e "EXPLAIN SELECT * FROM mysql.user" | mk-visual-explain
# 互動模式設定 pager
mysql> PAGER mk-visual-explain
mysql> EXPLAIN SELECT ...
實戰案例
建立測試表
CREATE TABLE article (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
author_id INT UNSIGNED NOT NULL,
category_id INT UNSIGNED NOT NULL,
views INT UNSIGNED NOT NULL,
comments INT UNSIGNED NOT NULL,
title VARBINARY(255) NOT NULL,
content TEXT NOT NULL
) ENGINE=InnoDB;
INSERT INTO article (author_id, category_id, views, comments, title, content) VALUES
(1,1,1,1,'1','1'), (2,2,2,2,'2','2'); -- 實測請插入數千筆
目標查詢
SELECT author_id FROM article
WHERE category_id = 1 AND comments > 1
ORDER BY views DESC LIMIT 1;
EXPLAIN 輸出關鍵欄位解讀
| 欄位 | 含義 | 優化方向 |
| type | 存取類型:system > const > eq_ref > ref > range > index > ALL | 避免 ALL (全表掃描),至少達到 range/ref |
| possible_keys | 可能用到的索引 | 無則需建立索引 |
| key | 實際使用的索引 | 與 possible_keys 比對 |
| key_len | 使用的索引長度 | 過長可能只有前綴被使用 |
| rows | 預估掃描行數 | 越小越好 |
| Extra | 額外資訊:Using where, Using index, Using filesort, Using temporary | 避免 filesort/temporary |
優化建議
- 為
category_id, comments, views 建立複合索引:INDEX idx_cat_comm_views (category_id, comments, views)。
- 利用覆蓋索引滿足
SELECT author_id,避免回表。
- 測試資料量需接近生產環境,否則優化器可能誤選索引。