EXPLAIN 是 SQL 調優的「聽診器」,通過在 SELECT 前加關鍵字,即可看到優化器如何訪問表、使用哪些索引、預估掃描行數等關鍵信息。
| 列名 | 含義 | 關鍵判讀 |
|---|---|---|
| id | SELECT 識別符,數字越大優先執行,相同則按順序 | 關注執行順序,衍生表 (derived) 通常 id 較大 |
| select_type | 查詢類型 | SIMPLE (無子查詢/UNION)、PRIMARY (最外層)、SUBQUERY、DERIVED (衍生表)、UNION/UNION RESULT |
| table | 訪問的表 (或衍生表別名) | <derived2> 表示來自 id=2 的衍生表 |
| partitions | 匹配的分區 (分區表才顯示) | 檢查分區裁剪是否生效 |
| type ⭐ | 訪問類型,效能由高到低 | system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL |
| possible_keys | 理論可用索引 | 為 NULL 表示無索引可用,需檢查 WHERE/JOIN 條件列 |
| key ⭐ | 實際選用索引 | 為 NULL 則全掃;可用 FORCE INDEX / IGNORE INDEX 干預 |
| key_len | 索引鍵長度 (字節) | 越短越好;推斷聯合索引用了幾列 (含 NULL 標誌 1 字節) |
| ref | 索引查找值來源 | const (常數)、col_name (關聯列)、func (函數結果) |
| rows ⭐ | 預估掃描行數 | 越小越好;配合 filtered (5.7+) 估算實際返回行 |
| filtered | 按表條件過濾後剩餘比例 % | 100 表示無額外過濾;低值說明需回表過濾大量行 |
| Extra ⭐ | 額外信息,紅綠燈信號 | 見下表 |
>, <, >=, <=, BETWEEN, IN, LIKE 'prefix%'),優於全表。| 信號 | 含義 | 動作 |
|---|---|---|
| 🟢 Using index | 覆蓋索引,僅讀索引不回表 | ✅ 保持 |
| 🟢 Using where | Server 層過濾 (非存儲引擎) | ✅ 正常 |
| 🟡 Using index condition (ICP) | 存儲引擎層推送索引條件 (5.6+) | ✅ 優化生效 |
| 🔴 Using filesort | 需額外排序 (無序索引或 ORDER BY 非索引列) | ⚡ 加索引/調整 ORDER BY |
| 🔴 Using temporary | 建立臨時表 (GROUP BY/DISTINCT/UNION 無索引) | ⚡ 加索引/改寫 SQL |
| 🔴 Range checked for each record | 無好索引,逐行嘗試選索引 | ⚡ 重設計索引 |
| 🟢 Distinct / Not exists | 優化器提前終止掃描 | ✅ 良好 |
type 至少達 ref,key 非 NULL,rows 最小化,Extra 無紅燈。EXPLAIN SELECT ... 獲取計劃。type=ALL → 檢查 WHERE/JOIN/ORDER BY 列是否有索引。Using filesort → 為 ORDER BY 列加索引 (注意方向一致)。Using temporary → 為 GROUP BY/DISTINCT 列加索引。key_len 過長 → 檢查聯合索引列序、字符集、NULL 屬性。EXPLAIN ANALYZE (8.0.18+) 看實際耗時與行數。pt-visual-explain 產生樹狀圖、EXPLAIN FORMAT=JSON (5.6.5+) 獲取成本信息。Using index condition (ICP)、EXPLAIN FOR CONNECTION。filtered 列、EXPLAIN PARTITIONS 預設開啟。EXPLAIN ANALYZE 實際執行統計、EXPLAIN FORMAT=TREE 可視化。熟練讀懂 EXPLAIN,是從「寫出能跑的 SQL」進階到「寫出跑得快的 SQL」的必經之路。