例子:
EXPLAIN SELECT * FROM users WHERE age > 18;
EXPLAIN 输出的列解析
每个 EXPLAIN 的输出结果包含如下关键字段:
列名 | 说明 |
---|---|
id | 查询中每个 SELECT 子句的标识符。id 越大优先级越低,执行顺序是从上到下。 |
select_type | SELECT 查询类型,表示是简单查询、子查询、联合查询还是派生表等。 |
table | 显示该行对应的表名,表示查询涉及到的表。 |
partitions | 使用的分区(仅在表有分区时显示)。 |
type | 连接类型,显示表的访问方式,重要程度从高到低依次是 system、const、eq_ref、ref、range 等。 |
possible_keys | 查询中可能会用到的索引。 |
key | 实际使用的索引。 |
key_len | 使用的索引长度,表示 MySQL 从索引中使用了多少字节。 |
ref | 显示索引列是否和哪些列或常量进行比较。 |
rows | 预估扫描的行数。该数字越小越好。 |
filtered | 过滤条件的百分比,即返回的行数占扫描行数的百分比。 |
Extra | 显示执行过程中额外的信息。 |
常见的 select_type 值
- SIMPLE: 简单查询,查询中不包含子查询或联合查询。
- PRIMARY: 查询的最外层,通常是主查询。
- SUBQUERY: 子查询。
- DERIVED: 派生表(子查询在 FROM 子句中,MySQL 会将其视为派生表)。
- UNION: 联合查询的一部分。
- DEPENDENT UNION: 联合查询的一部分,依赖于外部查询。
常见的 type 值(连接类型), 重要程度从高到低依次为:
- ALL: 全表扫描,性能最差。
- index: 全索引扫描,扫描所有索引项,而不是数据表。
- range: 范围扫描,只扫描指定范围的索引项,常用于 BETWEEN、>、< 等范围条件。
- ref: 非唯一索引扫描,返回匹配某一非唯一值的所有行,适用于主键或唯一索引以外的索引。
- eq_ref: 唯一索引扫描,返回匹配唯一索引值的行,通常在连接查询中用到。
- const/system: 当查询条件能匹配一个唯一索引的单条记录时使用,速度最快。
Extra 字段包含了查询优化器对查询进行的其他操作,以下是一些常见的值及其含义:
- Using where: 表示 MySQL 会在存储引擎返回数据后进行过滤。
- Using index: 表示查询仅通过索引满足请求,不需访问表的数据行,效率高。
- Using filesort: MySQL 需要额外的排序操作。ORDER BY 无法使用索引时,MySQL 会进行文件排序,效率较低。
- Using temporary: 查询过程中使用了临时表,通常出现在 GROUP BY、ORDER BY 等场景,性能会有所影响。
- Using join buffer: MySQL 在连接时使用了连接缓存,通常因为连接条件中的列没有索引。
- Using where; Using index: 通过索引完成数据查找且无全表扫描(覆盖索引)。
例子:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | users | range | age_index | age_index | 4 | NULL | 1000 | Using where |
分析:
type 为 range 表示使用了范围扫描。
key 使用的索引是 age_index
rows 为 1000 表示预估会扫描 1000 行数据,扫描行数较多,查询速度可能较慢。