EXPLAIN 輸出 MySQL 優化器對 SQL 的**執行計劃**:掃描順序、索引選擇、連接算法、預估掃描行數。是**慢查詢優化、索引設計驗證、執行路徑預判**的核心工具。
| 字段 | 含義 | 優化關注點 |
|---|---|---|
| id | SELECT 識別符,遞增;UNION 結果為 NULL | 多 SELECT 執行順序 |
| select_type | 查詢類型:SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、DEPENDENT SUBQUERY 等 | 子查詢優化目標:轉 JOIN、物化、半連接 |
| table | 訪問的表名 / <derivedN> / <unionM,N> | 關聯順序驗證 |
| partitions | 匹配的分區 (分區表) | 分區裁剪驗證 |
| type (關鍵) | 訪問類型/連接類型,效能由好到壞: system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL | 核心指標:至少達到 ref,避免 ALL/index |
| possible_keys | 可能用到的索引 | 為 NULL 表示無索引可用,需建索引 |
| key | 實際使用的索引 | 與 possible_keys 差異分析;可用 FORCE INDEX 指定 |
| key_len | 使用的索引長度 (字節) | 推斷聯合索引使用了幾列 (最左前綴) |
| ref | 與 key 配合的比較值:const、列名、函數 | 驗證關聯條件正確性 |
| rows (關鍵) | 預估掃描行數 | 越小越好;與實際行數對比驗證統計信息準確性 |
| filtered | 按表條件過濾後剩餘行百分比 (EXPLAIN EXTENDED) | 低百分比提示條件過濾性差 |
| Extra (關鍵) | 額外信息: Using index (覆蓋索引)、Using where (Server 層過濾)、Using temporary (臨時表)、Using filesort (外部排序)、Using join buffer (Block Nested Loop)、FirstMatch/LooseScan (半連接優化) | 重點優化目標:消除 filesort/temporary、爭取 Using index |
system:表僅 1 行 (系統表)const:主鍵/唯一索引與常數比較,最多 1 行,查詢優化階段常數折疊eq_ref:多表 JOIN 最優,關聯列為主鍵/唯一索引,**每次關聯精確匹配 1 行**ref:非唯一索引關聯,**匹配多行**,但行數可控時可接受index_merge:多索引 OR 合併,intersect/union/sort_union 三種策略range:索引範圍掃描 (>, <, BETWEEN, IN, LIKE 'prefix%')index:全索引樹掃描。Using index (覆蓋索引,僅掃描索引葉節點) — 可接受Using index (全索引掃描後回表/過濾) — **需優化**ALL:全表掃描 (最差),必須建索引或改寫 SQL
-- 原 SQL:臨時表 + 排序
SELECT * FROM orders WHERE status = 1 ORDER BY create_time DESC LIMIT 20;
-- EXPLAIN: Using where; Using temporary; Using filesort
-- 優化:建立覆蓋索引,順序匹配 WHERE + ORDER BY
ALTER TABLE orders ADD INDEX idx_status_ctime_id (status, create_time DESC, id DESC);
-- EXPLAIN: Using index condition; -- 無 temporary/filesort,直接索引下推返回
INDEX idx_a_b_c (a, b, c) -- a:4字節, b:4字節, c:4字節 (INT)
-- SQL: WHERE a=1 AND b=2 → key_len=8 (使用 a,b)
-- SQL: WHERE a=1 → key_len=4 (僅使用 a)
-- SQL: WHERE b=2 → key_len=NULL (無法使用,非最左)
rows 最小的表作為驅動表 (外層循環)Using join buffer (Block Nested Loop):被驅動表無索引,需優化關聯列索引
EXPLAIN EXTENDED SELECT * FROM t WHERE a > 10;
SHOW WARNINGS;
-- 可見優化器內部重寫後的 SQL、條件下推、常數傳播等優化動作
ANALYZE TABLE t 更新統計,或 innodb_stats_persistent=ON 持久化DEPENDENT SUBQUERY → 改寫為 JOIN 或 EXISTS,啟用 optimizer_switch='semijoin=on'EXPLAIN ANALYZE 實際執行並顯示真實耗時/行數、**可視化樹狀輸出** (EXPLAIN FORMAT=TREE)總結: 讀懂 EXPLAIN 是 DBA/開發進階的分水嶺。**重點盯三字段:type (訪問類型)、rows (掃描行數)、Extra (額外開銷)**。目標:type 至少 ref、rows 最小化、Extra 無 filesort/temporary、爭取 Using index。