执行计划是SQL语句经过查询分析器后得到的 抽象语法树 和 相关表的统计信息 作出的一个查询方案,这个方案是由查询优化器自动分析产生的。由于是动态数据采样统计分析出来的结果,所以可能会存在分析错误的情况,也就是存在执行计划并不是最优的情况。通过explain关键字知道MySQL是如何执行SQL查询语句的,分析select 语句的性能瓶颈,从而改进我们的查询,explain的结果如下:
重要的有id、type、key、key_len、rows、extra:
(1)id:id列可以理解为SQL执行顺序的标识,有几个select 就有几个id。
- id值不同:id值越大优先级越高,越先被执行;
- id值相同:从上往下依次执行;
- id列为null:表示这是一个结果集,不需要使用它来进行查询。
(2)select_type:查询的类型,主要用于区分普通查询、联合查询、子查询等复杂的查询;
(3)table:表示 explain 的一行正在访问哪个表
(4)type:访问类型,即MySQL决定如何查找表中的行。依次从好到差:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL,除了all之外,其他的 type 类型都可以使用到索引,除了 index_merge 之外,其他的type只可以用到一个索引。一般要求type为 ref 级别,范围查找需要达到 range 级别。
- system:表中只有一条数据匹配(等于系统表),可以看成 const 类型的特例
- const:通过索引一次就找到了,表示使用主键索引或者唯一索引
- eq_ref:主键或者唯一索引中的字段被用于连接使用,只会返回一行匹配的数据
- ref:普通索引扫描,可能返回多个符合查询条件的行。
- fulltext:全文索引检索,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引。
- ref_or_null:与ref方法类似,只是增加了null值的比较。
- index_merge:表示查询使用了两个以上的索引,索引合并的优化方法,最后取交集或者并集,常见and ,or的条件使用了不同的索引。
- unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值;
- index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
- range:索引范围扫描,常见于使用>,<,between ,in ,like等运算符的查询中。
- index:索引全表扫描,把索引树从头到尾扫描一遍;
- all:遍历全表以找到匹配的行(Index与ALL虽然都是读全表,但index是从索引中读取,而ALL是从硬盘读取)
- NULL:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引
(5)possible_keys:查询时可能使用到的索引
(6)key:实际使用哪个索引来优化对该表的访问
(7)key_len:实际上用于优化查询的索引长度,即索引中使用的字节数。通过这个值,可以计算出一个多列索引里实际使用了索引的哪写字段。
(8)ref:显示哪个字段或者常量与key一起被使用
(9)rows:根据表统计信息及索引选用情况,大致估算此处查询需要读取的行数,不是精确值。
(10)extra:其他的一些额外信息
- using index:使用覆盖索引
- using index condition:查询的列未被索引覆盖,where筛选条件使用了索引
- using temporary:用临时表保存中间结果,常用于 group by 和 order by 操作中,通常是因为 group by 的列上没有索引,也有可能是因为同时有group by和order by,但group by和order by的列又不一样,一般看到它说明查询需要优化了
- using filesort:MySQL有两种方式对查询结果进行排序,一种是使用索引,另一种是filesort(基于快排实现的外部排序,性能比较差),当数据量很大时,这将是一个CPU密集型的过程,所以可以通过建立合适的索引来优化排序的性能