使用mysql提供的explain命令来查询sql语句的执行计划,查看sql语句有没有使用上索引,有没有全表扫描等。
expain出来的信息有12列,分别是,id,select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,Extra。

如图:

一,概要描述
id:所泽标识符
select_type:表示查询的类型
table:输出结果集的表
partitions:匹配的分区
type:表示表的连接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引
key_len:索引字段的长度
ref:列与索引的比较
rows:扫描出的行数(估算的行数)
filtered:按表条件过滤的行百分比
Extra:执行情况的描述和说明

二、每个字段的详解

2.1 id

select识别符,这是select的查询序列号。
SQL执行的顺序的标识,SQL从大到小的执行。
1,id相同时,执行顺序由上至下。
2,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。
3,id如果相同,可以任务是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行。


 

2.2 select_type 

表示查询中每个select子句的类型。
2.2.1 simple (它表示简单的select,没有union和子查询)
2.2.2 primary (最外面的select,在有子查询的语句中,最外面的select查询就是primary)
2.2.3 union  (union语句的第二个或者是后面的select语句)
2.2.4 dependent union (union中的第二个或者后面的select语句,取决于外面的查询)
2.2.5 union result (union的结果,union语句中第二个select开始后面所有的select)
还有几个参数这里省略。

2.3 table

输出的行所用的表。

2.4 type

连接类型。有多个参数,从最佳类型到最差类型介绍

2.4.1 system
表仅有一行,这是const类型的特例,平时不会出现。

2.4.2 const
表最多有一个匹配行,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。若只是使用limit 1 来返回1条数据,type不会是const。如图,

2.4.3 eq_ref
对于每个来自前面的表的行组合,从该表中读取一行。这可能是最好的连接类型,除了const类型。他用在一个索引的所有部分被联接使用并且索引是unique或者primary key。

2.4.3 ref
对于每个来自前面的表的行组合,所有匹配索引值的行将从这张表读取。如果连接只使用键的最左边前缀,或如果键不是unique或者primary key,则使用ref。如果使用的键仅仅匹配少量行,该连接类型也是不错的。
如图中,where匹配了组合索引中的最左前缀。

2.4.5 ref_or_null
该连接类型如同ref,但是添加了mysql可以专门搜索包含NULL值的行。在解决子查询中经常使用该连接类型的优化。

2.4.6 index_merge
该连接类型表示使用索引合并优化方法,在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

2.4.7 unique_subquery

2.4.8 index_subquery

2.4.9 range
给定范围内的检索,使用一个索引来检查行。

2.4.10 index
该连接类型与all相同,除了只有索引树被扫描,这通常比ALL快,因为索引文件通常比数据文件小。(index是从索引中读取,而ALL是从磁盘中读取)

2.4.11 ALL

对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没有标记const的表,这通常这种情况不好,通常可以怎讲更多的索引而不要使用ALL,是的行能基于前面的表中的常数值或值被检索出。

2.5 possible_keys 
提示使用哪个索引会在该列中找到行,不太重要。

2.6 keys
mysql使用的索引,简单且重要。

2.7 key_len
mysql使用的索引长度。

2.8 ref
ref列显示使用哪列或常数与key一起从表中选择行

2.9 rows
显示mysql执行查询的行数,简单且重要,数值越大越不好,说明没有用好索引。

2.10 extra
该列包含了mysql解决查询的详细信息。

2.10.1 Distinct
Mysql发现第一个匹配行后,停止为当前的行组合搜索更多的行。

2.10.2 Not exists

2.10.3 range checked for each record
没有找到合适的索引

2.10.4 using filesort
当extra中出现using filesort时说明语句性能不好,需要优化。
using filesort是一种速度很慢的外部排序。
即使order by后的字段加了索引,也有可能出现using filesort,因为有可能索引定义不当,mysql没用到索引。
如下图中,UPPER_ID是单索引,DUTY_ID是组合索引的最左列。

2.10.5 using index(using index condition)
只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的信息。


2.10.6 using temporary
为了解决查询,mysql需要创建一个临时表来容纳结果,典型情况如查询包含客户以按不同情况列出列的group by和order by子句时,出现using temporary就说明语句需要优化。

2.10.7 using where
where子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行。如果extra值不为using where并且表示联接类型为ALL或index,查询可能会有一些错误。

2.10.8 using sort_union(), using union(...), using intersect(...)
这些函数说明如何为index_merge联接类型合并索引扫描。

2.10.9 using index for group-by
类似于访问表的using index方式,using index for group-by表示mysql发现了一个索引,可以用查询group by或distinct查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便于对每个组,只读取少量索引条目。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐