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