EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句,用法也十分简单:“Explain + sql语句”。
举例来看:
需要注意的是我本地的MySQL版本是5.7,5.7之前使用“Explain + sql语句”是没有上图的partitions和filtered这两个属性的,
如果版本之前需要使用“Explain partitions + sql语句”和“Explain extended+ sql语句”来显示的。当然5.7之后都成默认了。
官方文档中也有说明,感兴趣的可以参考下:
1:id
id是SELECT的标识符,它是在SELECT查询中的顺序编号,如果多表的话,id列数字越大越先执行,如果数字一样大则从上往下依次执行。下图则说明id都为1,但是先执行的是b表。
2:select_type
查询的类型,主要用于区别“普通查询,联合查询,子查询等复杂查询”。官方文档中记下可能出现的情况:
各项的说明如下:
①:simple:表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple,且只有一个。
②:primary:一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。且只有一个。
③:union:union连接的select查询,除了第一个表外,第二个及以后的表select_type都是union。
④:dependent union:与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
⑤:union result:包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
⑥:subquery:除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
⑦:dependent subquery:与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
⑧:derived:from字句中出现的子查询(衍生表)。
⑨:materialized:被物化的子查询
⑩:UNCACHEABLE SUBQUERY:对于外层的主表,子查询不可被物化,每次都需要计算(耗时操作)
?:UNCACHEABLE UNION:UNION操作中,内层的不可被物化的子查询(类似于UNCACHEABLE SUBQUERY)
其中常用的有①:simple,②:primary,③:union,⑤:union result,⑥:subquery,⑧:derived
3:table
显示这一行的数据是关于哪张表的。
4:partitions
显示的为分区表命中的分区情况。非分区表该字段为空(null)。
5:type
显示查询使用了何种类型。
完整的值有:从最好的到最次的排序为:system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL。
常用的值有:从最好的到最次的排序为:system>const>eq_ref>ref>range>index>ALL。
一般来说保证查询至少达到range级别,最好到ref。以下列出常用的说明:
①:system:表中只有一行数据或者是空表,这是const类型的特例。
②:const:使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描
③:eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
④:ref:非唯一性索引扫描,返回匹配每个单独值的所有行
⑤:range:索引范围扫描,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中
⑥:index:索引全表扫描,index和ALL区别为index类型只遍历索引树,通常比ALL快(index从索引读,ALL从硬盘中读)
⑦:ALL:全表扫描,将遍历全表找到匹配的行。
6:possible_key
显示可能应用在这张表上的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。
7:key
实际使用的索引,如果为NULL,则没有使用或者索引失效。查询中如果使用了覆盖索引,则该索引仅出现在key列表中
8:key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好(同样的查询结果下越短越好)。
key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
9:ref
显示索引的哪一列被使用了,如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,
如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func。
10:rows
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数(越少越好)
11:filtered
表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的百分比比例
12:extra
表示包含不适合在其他列中显示但十分重要的额外信息,列出常见的:
①:using filesort:排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中.
②:using temporary:使用了临时表保存中间结果,Mysql在对查询结果排序时使用了临时表。常见于order by和group by语句中.
③:using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。如果同时出现了using where,表明索引被用来执行索引键值的
查找,没有出现则表明索引用来读取数据而非执行查找动作。
④:using where:表示使用了where过滤
⑤:using join buffer :表示使用了连接缓存
⑥:impossible where:where子句的值总是false,不能用来获取任何元组
⑦:distinct:在select部分使用了distinc关键字
⑧:firstmatch(tb_name):常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个。
⑨:loosescan(m..n):在in()类型的子查询中,子查询返回的可能有重复记录时,就可能出现这个。
综上,比较重要的字段有"id,type,key,rows,extra"。