执行计划分析
约 1127 字大约 4 分钟
2025-08-30
执行计划(Execution Plan)是 SQL 语句经 MySQL 查询优化器优化后的具体执行方案,是 SQL 性能分析与优化的关键依据。通过 EXPLAIN 命令可获取执行计划,进而解析以下信息:
- 数据表的查询顺序
- 数据查询操作类型
- 可能命中与实际命中的索引
- 每张表的扫描行数
- 其他关键执行细节
执行计划字段
执行计划结果包含 12 列,含义如下:
| 列名 | 含义 |
|---|---|
id | SELECT 查询的序列号。相同 id 值表示同一组操作,按序从上到下执行;不同 id 值表示不同的查询组,id 值越大优先级越高。 |
select_type | 查询的类型,用于区分普通查询、联合查询、子查询等。 |
table | 当前操作所涉及的表名。 |
partitions | 匹配的分区信息,对于未分区的表,该列为 NULL。 |
type | 表访问方法,是衡量查询性能的关键指标,描述了 MySQL 如何查找表中的行。 |
possible_keys | 可能被查询优化器选择的索引列表。 |
key | 实际被查询优化器选择并使用的索引。如果为 NULL,表示没有使用索引。 |
key_len | 实际使用的索引的长度(字节数)。这个值可以帮助判断复合索引中使用了多少列。 |
ref | 表示与索引进行比较的列或常量。例如,const 表示常量,col_name 表示某个列。 |
rows | 预估扫描的行数,表示 MySQL 认为执行查询时必须检查的行数。此值越小越好。 |
filtered | 表示经过 WHERE 条件过滤后,剩余记录的百分比。该值越高,表示过滤效果越好。 |
Extra | 额外执行信息,包含 MySQL 执行查询的详细信息和潜在的性能警告。 |
select_type
查询的类型,主要用于区分普通查询、联合查询、子查询等复杂的查询,常见的值有:
| 类型 | 说明 |
|---|---|
SIMPLE | 简单的 SELECT 查询,不包含 UNION 或子查询。 |
PRIMARY | 对于包含子查询或 UNION 的复杂查询,此为最外层 SELECT。 |
SUBQUERY | 在 FROM 子句之外的子查询中的首个 SELECT。 |
DERIVED | 在 FROM 子句中的子查询(派生表)中的 SELECT。 |
UNION | UNION 操作中,第二个或后续 SELECT。 |
UNION RESULT | UNION 操作的结果集。 |
type
查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
常见的几种类型具体含义如下:
| 类型 | 说明 |
|---|---|
system | 表中只有一行数据(系统表),这是 const 类型的一个特例,直接从内存中返回。 |
const | 通过主键或唯一索引进行等值查询,并且查询优化器将查询转换为一个常量。仅扫描一行数据。 |
eq_ref | 在联表查询中,使用主键或唯一索引作为连接条件。对于驱动表的每一行,被驱动表仅匹配一行。 |
ref | 使用非唯一索引进行等值查询。可能会匹配到多行数据。 |
index_merge | 表示使用了索引合并优化,即利用多个索引来查找并合并结果集。 |
range | 对索引进行范围扫描,例如 BETWEEN, >, <, >= 等操作。 |
index | 全索引扫描,通过遍历整个索引树来获取数据。通常比 ALL 效率高,因为无需回表,但仍需扫描所有索引条目。 |
ALL | 全表扫描,表示 MySQL 遍历整个表来查找匹配的行。这是性能最差的类型,通常需要优先优化。 |
Extra
Extra 列包含了 MySQL 解析查询的额外信息,通过这些信息,可以更准确的理解 MySQL 到底是如何执行查询的。常见的值如下:
| 值 | 说明 | 性能影响 |
|---|---|---|
Using index | 使用覆盖索引(无需回表) | ✅ 高效 |
Using index condition | 使用索引条件下推(存储引擎层提前过滤) | ✅ 优化生效 |
Using where | 使用 WHERE 过滤(未用索引时出现) | ⚠️ 需检查索引使用 |
Using filesort | 文件排序(磁盘排序,非索引排序) | ❌ 高开销,需优化 |
Using temporary | 创建临时表(常见于 GROUP BY / ORDER BY) | ❌ 高开销,需优化 |
Using join buffer | 使用连接缓存(驱动表未用索引时出现) | ⚠️ 建议优化关联字段索引 |
重要警示
出现 Using filesort 或 Using temporary 通常预示性能瓶颈,需优先优化。