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 官方文档,此处只做简单记录

  1. type

大致可以理解为扫描方式,从最好到最差为:

  • system 该表只有一行(= 系统表)。这是 const 连接类型的特殊情况。
  • const 使用主键或者唯一索引查询时,会使用 const
  • eq_ref 一般出现在多表联查,且连接的字段是主键索引或者唯一索引
  • ref 使用非主键索引或非唯一索引查询
  • fulltext 使用 fulltext 索引查询
  • index_merge 使用了索引合并优化,参考索引合并优化
  • range 使用索引范围查询
  • index 与 all 相同,只是扫描了索引树
  • ALL 全表扫描
  1. possible_keys 使用的索引
  2. key 实际使用的索引
  3. rows 用来表示在 SQL 执行过程中会被扫描的行数,该数值越大,意味着需要扫描的行数,相应的耗时更长。但是对于 InnoDB 表,此数字是估计值,可能并不总是准确的
  4. 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

# 参考

  1. MySQL 5.7 Reference Manual - 8.8.2 EXPLAIN Output Format