MySQL EXPLAIN 完全指南:讀懂執行計劃,精準優化慢查詢
EXPLAIN 是 MySQL 查詢優化的核心工具。本文詳細解析每列含義、type 類型優劣排序、Extra 關鍵信息解讀,並給出優化實戰清單。
一、基礎用法
EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 1;
-- 或
EXPLAIN FORMAT=JSON SELECT ... -- 5.6+ 輸出 JSON,含更多信息
EXPLAIN ANALYZE SELECT ... -- 8.0.18+ 實際執行並統計耗時
二、核心列詳細解析
| 列名 | 含義 | 關鍵解讀 |
| id | 查詢標識符,包含子查詢時遞增 | 相同 id 從上往下執行;id 越大優先級越高 |
| select_type | 查詢類型 | SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、UNION RESULT |
| table | 訪問的表(或衍生表別名) | <derived2> 表示衍生表 |
| partitions | 匹配的分區 | 分區表才顯示 |
| type | 訪問類型(核心指標) | 見下表優劣排序 |
| possible_keys | 可能用到的索引 | 為 NULL 表示無索引可用 |
| key | 實際使用的索引 | 為 NULL 表示全表掃描 |
| key_len | 使用索引的字節長度 | 越短越好;可推斷聯合索引用了幾列 |
| ref | 與索引比較的列/常量 | const、func、列名 |
| rows | 預估掃描行數 | 越小越好;統計信息不準時偏差大 |
| filtered | 按條件過濾後剩餘行百分比 | 越高越好;100 表示無額外過濾 |
| Extra | 額外信息(關鍵優化線索) | 見下表關鍵值 |
三、type 類型優劣排序(由優到劣)
| 類型 | 含義 | 典型場景 | 效能 |
| system | 表僅一行(系統表) | 極少見 | ⭐⭐⭐⭐⭐ |
| const | 主鍵/唯一索引等值查詢,最多一行 | WHERE id=1 | ⭐⭐⭐⭐⭐ |
| eq_ref | 唯一索引/主鍵 JOIN,每行匹配一行 | ON t1.id=t2.id (t2.id 唯一) | ⭐⭐⭐⭐ |
| ref | 非唯一索引等值查詢/JOIN | WHERE status=1 | ⭐⭐⭐ |
| fulltext | 全文索引 | MATCH ... AGAINST | ⭐⭐⭐ |
| ref_or_null | ref + NULL 值補充 | WHERE col=1 OR col IS NULL | ⭐⭐⭐ |
| index_merge | 多索引合併 | WHERE a=1 OR b=2 | ⭐⭐ |
| unique_subquery | IN 子查詢主鍵 | WHERE id IN (SELECT id FROM t) | ⭐⭐ |
| index_subquery | IN 子查詢非主鍵索引 | WHERE col IN (SELECT col FROM t) | ⭐⭐ |
| range | 索引範圍掃描 | WHERE id > 100 | ⭐⭐ |
| index | 全索引掃描 | 覆蓋索引查詢 | ⭐ |
| ALL | 全表掃描 | 無索引或索引失效 | ⭐ (最差) |
目標: 核心查詢至少達到 ref 級別,避免 ALL。
四、Extra 關鍵值解讀
| 值 | 含義 | 優化方向 |
| Using index | 覆蓋索引,僅讀索引不回表 | ✅ 優秀,繼續保持 |
| Using where | Server 層過濾(非存儲引擎) | ⚠️ 檢查索引是否可下推 (ICP) |
| Using index condition | 索引條件下推 (ICP),存儲引擎層過濾 | ✅ 5.6+ 優化特性 |
| Using temporary | 創建臨時表(ORDER BY/GROUP BY/DISTINCT) | ❌ 優化索引順序、避免文件排序 |
| Using filesort | 外部排序(無索引支持排序) | ❌ 添加排序列索引、調整 ORDER BY |
| Using join buffer | 使用連接緩衝區(無索引 JOIN) | ❌ 為 JOIN 列添加索引 |
| Impossible WHERE | WHERE 條件恒假 | ✅ 優化器已優化掉 |
| Select tables optimized away | 聚合查詢無 GROUP BY,優化器直接返回 | ✅ 極優 |
| Range checked for each record | 無理想索引,逐行檢查索引 | ❌ 添加合適聯合索引 |
五、優化實戰清單
type=ALL → 檢查 possible_keys,添加適當索引。
Using filesort → 為 ORDER BY 列添加索引,或調整 ORDER BY 方向與索引一致。
Using temporary → GROUP BY/DISTINCT 列加索引,或用聯合索引覆蓋。
key_len 過長 → 聯合索引列過多/字符集 utf8mb4 導致,考慮前綴索引或縮短列。
rows 巨大但 filtered 低 → 統計信息過期,執行 ANALYZE TABLE。
- 衍生表
<derivedN> → 考慮物化視圖、CTE (8.0+)、或手動建臨時表。