EXPLAIN 语句提供有关 MySQL 如何执行语句的信息,适用于 SELECT 、 DELETE 、 INSERT 、 REPLACE 和 UPDATE 语句。
执行后返回以下信息:
Column 柱子 | JSON Name JSON 名称 | Meaning 意义 |
id | select_id | The SELECT identifier SELECT 标识符 |
select_type | None 没有任何 | The SELECT type SELECT 类型 |
table | table_name | The table for the output row <br> 输出行的表 |
partitions | partitions | The matching partitions 匹配的分区 |
type | access_type | The join type 连接类型 |
possible_keys | possible_keys | The possible indexes to choose <br> 可以选择的索引 |
key | key | The index actually chosen <br> 实际选择的索引 |
key_len | key_length | The length of the chosen key <br> 所选密钥的长度 |
ref | ref | The columns compared to the index <br> 列与索引的比较 |
rows | rows | Estimate of rows to be examined <br> 估计要检查的行数 |
filtered | filtered | Percentage of rows filtered by table condition <br> 按表条件过滤的行的百分比 |
Extra | None 没有任何 | Additional information 附加信息 |
更详细的解释建议查看 MySQL 官方文档,此处只做简单记录
- type
大致可以理解为扫描方式,从最好到最差为:
- system 该表只有一行(= 系统表)。这是 const 连接类型的特殊情况。
- const 使用主键或者唯一索引查询时,会使用 const
- eq_ref 一般出现在多表联查,且连接的字段是主键索引或者唯一索引
- ref 使用非主键索引或非唯一索引查询
- fulltext 使用 fulltext 索引查询
- index_merge 使用了索引合并优化,参考索引合并优化
- range 使用索引范围查询
- index 与 all 相同,只是扫描了索引树
- ALL 全表扫描
- possible_keys 使用的索引
- key 实际使用的索引
- rows 用来表示在 SQL 执行过程中会被扫描的行数,该数值越大,意味着需要扫描的行数,相应的耗时更长。但是对于 InnoDB 表,此数字是估计值,可能并不总是准确的
- extra EXPLAIN 输出的 Extra 列包含有关 MySQL 如何解析查询的附加信息。例如:
- Using where: where 条件查询
- Using index: 仅使用索引树中的信息从表中检索列信息,而无需执行额外的查找来读取实际行,就是常说的覆盖索引。
- Using index condition: 查询利用到了索引下推
- Using filesort: 如果排序的字段需要进行额外的查询按顺序排序
- Using temporary: 创建了临时表,一般在 group by 语句或者 order by 语句中出现
- 参考 EXPLAIN Extra Information
# 总结
一般情况下只需要看 type 列,查看扫描方式即可,例如 ALL 效率最差,那就应该根据查询字段或者业务添加索引,优化查询效率。有时候也会查看 extra 列的信息,例如 Using filesort,如果数据量特别大的情况,出现了该信息可能会导致查询较慢,可以结合业务为排序的字段与查询的字段添加组合索引,利用覆盖索引优化 Using filesort
# 参考
- MySQL 5.7 Reference Manual - 8.8.2 EXPLAIN Output Format