[MYSQL]-EXPLAIN用法

EXPLAIN简介

  当我们需要优化一个SQL语句的时候,我们需要知道该SQL的执行计划,比如是全表扫描,还是索引扫描;在MySQL中我们可以通过EXPLAIN去完成,EXPLAIN命令是查看优化器如何决定执行查询的主要方法。可以帮助我们深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。

  在select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询时,会返回执行计划的信息,而不是执行这条SQL(如果 from 中包含子查询,仍会执行该子查询,将结果放入临时表中)。

执行计划各字段含义

EXPLAIN输出字段包含id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra几项信息。

一、ID

  ID是用来顺序标识整个查询中SELELCT 语句的,在嵌套查询中id越大的语句越先执行。该值可能为NULL,如果这一行用来说明的是其他行的联合结果。

ID列的值越大,执行优先级越高,id相同则从上往下执行,id值如果为NULL则最后执行。

二、SELECT_TYPE

  select_type表示对应行的查询类型是简单查询还是复杂的查询,分为以下几类:

  1、simple:表示简单子查询,不包含子查询和union;

  2、primary:表示复杂查询中最外层的 select

  3、subquery:一般子查询中的子查询被标记为subquery,也就是位于select列表中的查询;

  4、derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表;

  5、union:位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是union位于from中则标记为derived;

三、TABLE

  TABLE表示对应行正在访问哪一个表,表名或者别名;

  •  关联优化器会为查询选择关联顺序,左侧深度优先;
  •  from中有子查询的时候,表名是derivedN的形式,N指向子查询,也就是explain结果中的下一列;
  • 当有union result的时候,表名是union 1,2等的形式,1,2表示参与unionquery id;

MySQL对待这些表和普通表一样,但是这些临时表是没有任何索引的。

四、TYPE

  type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref;

  type也可能出现NULL值,NULL值是mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问表。

  1、system:只有一条数据的系统表,或派生表只有一条数据的子查询;

  2、const:当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快。当主键放入where子句时,mysql把这个查询转为一个常量(高效);

  3、eq_ref:唯一性索引,对于每个键的查询,最多只返回一条符合条件的记录。使用唯一性索引或主键查找时会发生 (高效);

  4、ref:非唯一性索引,对于每个索引键的查询,返回匹配所有行(0,多);

  5、range:检索指定范围的行,key 列显示使用了哪个索引,where后面是一个范围查询(between,>,<,>=,in有时候会失效,从而转为无索引ALL);

  6、index:和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大。如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多;

  7、all:最坏的情况,全表扫描;

五、POSSIBLE_KEYS

  显示查询有可能会使用到哪些索引,表示该索引可以进行高效地查找,但是列出来的索引对于后续优化过程可能是没有用的,只是一种预测;

六、KEY

  key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEXUSE INDEX或者IGNORE INDEX

七:KEY_LEN

  key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好。

八、REF

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

九、ROWS

  rows列显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。

十、EXTRA

  ExtraEXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。

  1、Using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序;

  2、Using temporary:用临时表保存中间结果,常用于GROUP BY ORDER BY操作中,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用;

  3、Not existsMYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了;

  4、Using index: 说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现using where,表明索引被用来执行索引键值的查找,没有using where,表明索引用来读取数据而非执行查找动作。这是MySQL服务层完成的,但无需再回表查询记录;

  5、Using index condition: MySQL 5.6加入的新特性,。简单说一点就是MySQL原来在索引上是不能执行如like这样的操作的,但是现在可以了,这样减少了不必要的IO操作,但是只能用在二级索引上;

  6、Using where: 表明使用了where 过滤。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤;

  7、Using join buffer: 表示使用了连接缓存;

  8、impossible where: where子句的值总是false,不能选择任何行;

  9、select tables optimized away:在没有GROUP BY子句的情况下,基于索引优化MIN/MAX操作,或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化;

  10、Distinct:优化distinct操作,在找到第一匹配的行后它将停止找更多的行;  

 

 

本文根据平时使用并结合其他资料整理以作为笔记备忘,文中如有存在描述不正确,欢迎指正、补充!!!

猜你喜欢

转载自www.cnblogs.com/ljch/p/12080146.html