基础语法
EXPLAIN SELECT ... -- 分析查询执行计划
EXPLAIN EXTENDED SELECT ... -- 显示额外优化器信息(5.7+ 默认开启)
EXPLAIN tbl_name -- 等同 DESC tbl_name / SHOW COLUMNS FROM tbl_name
输出列详解
| 列名 | 含义 | 关键值解读 |
id | SELECT 标识符,编号递增表示执行顺序 | 相同 id 从上到下执行;id 越大越先执行(子查询) |
select_type | 查询类型 | 见下表 |
table | 访问的表/衍生表 | <derivedN> 表示派生表(子查询结果集) |
partitions | 匹配的分区(分区表) | — |
type | 访问类型(核心性能指标) | system > const > eq_ref > ref > range > index > ALL |
possible_keys | 可能用到的索引 | NULL 表示无可用索引 |
key | 实际使用的索引 | NULL 表示全表扫描 |
key_len | 索引长度(字节) | 推断联合索引用了几列 |
ref | 与索引比较的列/常量 | const、func、列名 |
rows | 预估扫描行数 | 越小越好,统计信息不准时偏差大 |
filtered | 按条件过滤后剩余行百分比 | 100 表示无过滤 |
Extra | 额外信息 | 见下表 |
select_type 取值
| 值 | 含义 |
| SIMPLE | 简单查询(无子查询/UNION) |
| PRIMARY | 最外层查询 |
| UNION | UNION 中第二个及后续 SELECT |
| DEPENDENT UNION | 依赖外部查询的 UNION |
| UNION RESULT | UNION 合并结果 |
| SUBQUERY | 子查询中第一个 SELECT |
| DEPENDENT SUBQUERY | 依赖外部查询的子查询 |
| DERIVED | FROM 子句中的派生表 |
| UNCACHEABLE SUBQUERY/UNION | 结果不可缓存,每行重新评估 |
type 访问类型(由优到劣)
system:表仅一行(const 特例)。
const:主键/唯一索引等值查询,最多一行,极快。
eq_ref:唯一索引/主键等值连接,每行匹配一行。
ref:非唯一索引等值连接/查询,匹配多行。
ref_or_null:ref + 额外搜索 NULL。
index_merge:索引合并优化(Using union/intersect/sort_union)。
unique_subquery:IN 子查询主键优化。
index_subquery:IN 子查询非唯一索引优化。
range:索引范围扫描(BETWEEN、IN、>、< 等)。
index:全索引扫描(覆盖索引时常见)。
ALL:全表扫描(最差)。
Extra 关键信息
| 值 | 含义 | 优化方向 |
| Using index | 覆盖索引(仅读索引) | ✅ 优秀 |
| Using where | Server 层过滤 | ⚠️ 结合索引下推 |
| Using temporary | 需创建临时表(GROUP BY/ORDER BY 无索引) | ❌ 优化索引/避免临时表 |
| Using filesort | 需文件排序(ORDER BY 无索引) | ❌ 增加排序索引 |
| Using join buffer | 连接使用 Join Buffer(无索引) | ❌ 加连接索引 |
| Impossible WHERE | WHERE 恒假 | ✅ 无需执行 |
| Select tables optimized away | 聚合函数直接用索引 | ✅ 极快 |
实战案例演示
案例 1:主键等值查询(const)
EXPLAIN SELECT * FROM books WHERE book_id = 1;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | books | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
案例 2:嵌套子查询执行顺序
EXPLAIN SELECT * FROM (SELECT * FROM (SELECT * FROM t3 WHERE id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | | system | NULL | NULL | NULL | NULL | 1 | |
| 3 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
执行顺序:id=3 → id=2 → id=1(从内向外)。
案例 3:UNION 与 DEPENDENT SUBQUERY
EXPLAIN SELECT * FROM t3 WHERE id IN (SELECT id FROM t3 WHERE id=3952602 UNION ALL SELECT id FROM t3);
+----+--------------------+-------+--------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+-------------------+---------+---------+-------+------+--------------------------+
| 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 1000 | Using where |
| 2 | DEPENDENT SUBQUERY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | Using index |
| 3 | DEPENDENT UNION | t3 | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4 | func | 1 | Using where; Using index |
|NULL| UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------------+-------+--------+-------------------+---------+---------+-------+------+--------------------------+
外层 PRIMARY 走全表扫描(ALL),子查询部分走索引。
优化清单
type=ALL → 检查 WHERE/JOIN 列是否有索引,考虑添加复合索引。
Using filesort / Using temporary → 增加 ORDER BY/GROUP BY 对应索引,或调整 SQL 逻辑。
key=NULL 但 possible_keys 有值 → 索引选择性太低,优化器放弃,考虑 FORCE INDEX 或重写查询。
rows 极大 → 分区表、分库分表、增加过滤条件。
- 定期
ANALYZE TABLE 更新统计信息,保证优化器决策准确。