Explain的使用及字段说明

Posted zqq_hello_world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Explain的使用及字段说明相关的知识,希望对你有一定的参考价值。

Explain

Explain命令是查看查询优化器如何决定执行查询的主要方法。使用Explain只需要在查询中的SELECT关键字之前增加Explain关键字,mysql会在查询上设置一个标记,当执行查询时,这个标记会使其返回关于在执行计划中每一步的信息,而不是执行它(如果查询在FROM子句中包括子查询,那么Mysql会执行子查询,将其结果放在一个临时表中)。它会返回一行或者多行信息,显示出执行计划中的每一步和执行次序。

Explain中的列

  1. id

    id列是一个编号,标识SELECT所属的行,如果在语句中没有子查询或者联合查询,那么只会有一个SELECT,每一行这个列的会显示1。内存的SELECT语句一般都会顺序编号,对应其在原始语句中的位置,可以用SELECT后的子查询测试。

  2. select_type

    这一例显示对应的是简单的还是复杂的SELECT。值为SIMPLE意味着查询不包括子查询和UNION,如果查询有任何复杂子部分,则最外层标记为PRIMARY,例如SQL:

    -- 简单的子查询
    EXPLAIN SELECT a.*,(SELECT count(*) FROM b_order b where b.account = a.account) from a_order a;
    

  1. table

    显示对应行正在访问哪个表,通常情况下就是表名,如果sql中定义了别名就是表的别名。

  2. type

    访问类型,表示sql是如何查找表中的行。从最差到最优依次如下:

    • ALL

      全表扫描,意味着Mysql必须扫描整张表,从头到尾去找到需要的行。(也有例外情况,比如查询里使用了limit,或者Extra列中显示Using distinct/not exists)

      -- 非索引字段搜索,type = ALL
      EXPLAIN SELECT * from a_order where `month` = '201810';
      
    • index

      跟全表扫描一样,只是Mysql扫描表时按索引次序进行而不是行。主要优点是避免了排序;最大的缺点是要承担按索引次序读取整个表的开销。如果在Extra列中看到Using Index说明Mysql正在使用覆盖索引,它只扫描索引的数据,而不是按索引次序的每一行。它比按索引次序全表扫描的开销要少很多。

      -- type = index
      EXPLAIN SELECT * from a_order where `month` = '201810' order by id DESC;
      
    • range

      范围扫描。是一个有限制的索引扫描,它开始于索引里的某一点,返回匹配这个值域的行。比全索引扫描好一些,因为不需要遍历全部索引。显而易见的范围扫描是带有BETWEEN或在WHERE子句里带有>的查询。

      -- type = range
      EXPLAIN SELECT * from a_order where id BETWEEN 1000 and 2000;
      
    • ref

      是一种索引访问,它返回所有匹配某个单个值的行。它可能会找到多个符号条件的行,因此它是查找和扫描的混合体。此类索引访问只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。

      -- type = ref,account字段添加了索引
      EXPLAIN SELECT * FROM a_order where account = 'joe8';
      
    • eq_ref

      使用这种索引查找,Mysql知道最多只返回一条符合条件的记录。这种访问方法可以在Mysql使用主键或者唯一性索引查找时看到。

    • const、system

      当Mysql能对查询的部分进行优化并将其转换成一个常量时,就就会使用这些访问类型。

      -- type = const
      EXPLAIN SELECT * from a_order where id = '946265';
      
    • NULL

      这种访问方式意味着Mysql能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。例如:从一个索引列里选取最小值可以通过单独查找索引来完成,不需要在执行时访问表。

  3. possible_keys

    这一列显示了查询可以使用哪些索引,这是基于查询访问的列和使用比较操作符来判断的。这个列表是在优化过程早期创建的,因此有些罗列出来的索引可能对于后续优化过程是没用的。

  4. key

    这一列显示了Mysql决定采用哪个索引来优化对该表的访问。如果该索引没有出现在possible_keys列中,那么Mysql选用它是出于另外的原因,列如。它可能选择了一个覆盖索引。哪怕没用where子句。

    possible_keys揭示了哪一个索引能有助于高效地进行查找,key显示的是优化采用哪一个索引可以最小化查询成本。

  5. key_len

    该列显示了Mysql在索引里使用的字节数。

  6. ref

    这一列显示了之前的表在key列记录的索引中查找的列或常量。

  7. rows

    Mysql估计为了找到所需的行而要读取的行数。它不是Mysql最终从表里取出来的行数,而是Mysql为了找到符号查询的每一点上标准的那些行而必须读取行的平均数

  8. filtered

    filtered显示的是针对表里符合某个条件的记录数的百分比所做的一个悲观估值。越大越好。

  9. Extra

    这一列包含的是不适合在其他列显示的额外信息。

    常见的重要值如下:

    • Using index

      此值标识MySQL将使用覆盖索引,以避免访问表。

    • Using where

      意味着Mysql服务器将在存储引擎检索行后再进行过滤。

    • Using temporary

      意味着Mysql在查询结果排序时会使用一个临时表。

    • Using filesort

      意味着Mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。

以上是关于Explain的使用及字段说明的主要内容,如果未能解决你的问题,请参考以下文章

explain结果字段说明

mysql索引优化及explain关键字段解释

mysql explain执行计划分析

如何判断索引是否生效--explain

MySQL命令 Explain参数说明

explain用法常用词组