MySQL优化之Explain

EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句,用法也十分简单:“Explain + sql语句”。

举例来看:

 需要注意的是我本地的MySQL版本是5.7,5.7之前使用“Explain + sql语句”是没有上图的partitionsfiltered这两个属性的,

如果版本之前需要使用“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,typekeyrowsextra"。

原文地址:https://www.cnblogs.com/-qilin/p/12747481.html