mysql explain结果中的每一列意义

explain 输出中的行以mysql实际执行的查询部分的顺序出现,而这个顺序不总是与其在原始SQL中的一致

id:    select识别符。这是select的查询序列号。

select_type: select 类型
SIMPLE:查询不包括子查询和UNION
SUBQUERY:包含在select 列表中的子查询,不在from 子句中,标记为SUBQUERY。
DERIVED:标记包含在from 中的子查询,mysql会递归查询并将结果放到一个临时表中。服务器内部称其“派生表”
UNION:联合查询,在UNION 中第二个和随后的查询被标记为UNION。第一个select以部分外查询来执行,所以被显示为primary。如果UNION被from子句中的子查询包含,那么它的第一个select
会被标记为derived
UNION RESULT: 用来从union的匿名临时表检索结果的select被标记为UNION RESULT。
除了这些, SUBQUERY和UNION还可以被标记为DEPENDENT何UNCACHEABLE。DEPENDENT意味着select依赖于外层查询中发现的数据。UNCACHEABLE意味着select中的某些特性阻止结果被缓存于一个Item_cache中。(Item_cache未被文档记载,它与查询缓存不是一回事,尽管它可以被一些相同类型的构件否定,例如RAND()函数。)


table: 对应行正在访问的表。如果是派生表和联合表会复杂很多。
1)、当在from子句中有子查询时,table列是的形式,其中N是子查询的id。这总是“向前引用”,即N指向explain输出中后面的一行。
2)、当有union时,union result的table列包含一个参与union的id列表。这总是“向后引用”,因为union result出现在union中所有参与行之后


type: 表示表的连接类型,更准确的说法是访问类型——换言之就是mysql决定如何查找表中的行。依次从最差到最优:
1) ALL:这就是所谓的全表扫描
2) index:这个跟全表扫描一样,只是mysql扫描表时按索引次序而不是行,它的主要优点是避免了排序;最大缺点是要承担按索引次序读取整个表的开销。这通常意味着若是按随机次序访问行,开销将非常大。如果在extra列中看到“Using index”,说明mysql正在使用索引覆盖,它只扫描索引的数据,而不是按索引次序的每一行(如select id from table,只用到索引的数据,不用索引数据文件),它比按索引次序全表扫描的开销要少很多。
3) range:范围扫描就是一个有限制的索引扫描,它开始与索引里的某一点,返回匹配这个值域的行,这比全索引扫描要好一点,因为它用不着遍历全部索引,显而易见的扫描是带有between或在where子句里带有>的查询。    当mysql使用索引去查找一系列值时,例如in()和or列表,也会显示为范围扫描,然而,这两者其实是相当不同的访问类型,在性能上有重要的差异(结论: or的效率为O(n),而in的效率为O(logn),如果in和or所在列有索引或者主键的话,or和in没啥差别,执行计划和执行时间都几乎一样。如果in和or所在列没有索引的话in效率高。)。此类扫描的开销跟索引类型的相当。
4) ref:这是一种索引访问(有时也叫做索引查找),它返回所有匹配某个单个值的行,然而,它可能会找到多个符合条件的行。因此,它是查找和扫描的混合体,此类索引访问只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。把它叫做ref是因为索引要跟某个参考值相比较。这个参考值或者是一个常数,或者是来自多表查询前一个表里的结果值。
    ref_or_null是ref之上的一个变体,它意味着mysql必须在初次查找的结果里进行第二次查找以找出null条目。
5) eq_ref:使用这种索引查找,mysql知道最多只返回一条符合条件的记录,这种访问方法可以在mysql使用主键或者唯一性索引查找时看到,它会将它们与某个参考值做比较。mysql对于这类访问类型的优化做得非常好,因为它知道无需估计匹配行的范围或在找到匹配行后再继续查找。
6) const,system:当mysql能对查询的某部分进行优化并将其转换成一个常量时,他就会使用这些访问类型,举例来说,如果你通过将某一行的主键放入where子句里的方式来选取此行的主键,mysql就能把这个查询转换为一个常量,然后就可以高效地将表从联接执行中移除。
7) null:这种访问方式意味着mysql能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。例如,从一个索引列里选取最小值可以通过单独查找索引来完成,不需要在执行时访问表。
当表中仅有一行是type的值为system是最佳的连接类型;
当select操作中使用索引进行表连接时type的值为ref;
当select的表连接没有使用索引时,经常会看到type的值为ALL,表示对该表进行了全表扫描,这时需要考虑通过创建索引来提高表连接的效率。

possible_keys: 表示查询时,可以使用的索引列,这是基于查询访问的列和使用的比较操作符来判断的。


key: mysql决定采用的索引来优化对该表的访问。如果该索引没有出现在possible_keys列中,那么mysql选用它是处于另外的原因,如它可能选择了一个覆盖索引,哪怕没有where子句。possible_keys揭示了哪一个索引能有助于高效地进行查找,而key显示的是优化采用哪一个索引可以最小化查询成本。

key_len: 列显示了在索引字段中可能的最大长度,而不是表中数据使用的实际字节数,换言之,key_len通过查找表的定义而被计算出,而不是表中的数据。

ref:显示了之前的表在key列记录的索引中查找值所用的列或常量

rows: 这一列是mysql估计为了找到所需的行而要读取的行数。这个数字是内嵌循环关联计划里的 循环数目,也就是说它不是mysql认为它最终要从表里读取出来的行数,而是mysql为了找到符合查询的每一点上标准的那些行而必须读取的行的平均数。


Extra: 包含的是不适合在其他列显示的额外信息。常见的最重要的值如下:
1)、Using index  此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
2)、Using where  这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
3)、Using temporary 这意味着mysql在对查询结果排序时会使用一个临时表。
4)、Using filesort 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
5)、Range checked for each record(index map: N)

    这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。


explain extended 命令加上SHOW WARNINGS 可以查看到sql 被优化前做了那些sql 的改写。

你可能感兴趣的:(mysql)