文章会有【原创】或者【转载】标示,部分来自Google Baidu的学习结果 {Java/PHP/Python/Ruby/Go}

MySQL Explain详解【原创】  


MySQL Explain

[phper.yang www.imop.us]

列名

描述

说明

相关链接

id

若没有子查询和联合查询,id则都是1

Mysql会按照id从大到小的顺序执行query,在id相同的情况下,则从上到下执行。


select_type

select类型。



table

输出的行所引用的表。

有时看到的是<derivedN>,其中N对应的是id列的值。


type

Mysql的存取方法,连接访问类型。



possible_keys

在查询过程中可能用到的索引。

在优化初期创建该列,但在以后的优化过程中会根据实际情况进行选择,所以在该列列出的索引在后续过程中可能没用。该列为NULL意味着没有相关索引,可以根据实际情况看是否需要加索引。


key

访问过程中实际用到的索引。

有可能不会出现在possible_keys(这时可能用的是覆盖索引,即使query中没有where)possible_keys揭示哪个 索引更有效,key是优化器决定哪个索引可能最小化查询成本,查询成本基于系统开销等总和因素,有可能是执行时间矛盾。如果强制mysql使用或者忽 略possible_keys中的索引,需要在query中使用FORCE INDEXUSE INDEX或者IGNORE INDEX


key_len

显示使用索引的字节数。

由根据表结构计算得出,而不是实际数据的字节数。如ColumnA(char(3)) ColumnB(int(11)),在utf-8的字符集下,key_len=3*3+4=13。计算该值时需要考虑字符列对应的字符集,不同字符集对应不同的字节数。


ref

显示了哪些字段或者常量被用来和 key 配合从表中查询记录出来。显示那些在index查询中被当作值使用的在其他表里的字段或者constants



rows

估计为返回结果集而需要扫描的行。

不是最终结果集的函数,把所有的rows乘起来可估算出整个query需要检查的行数。有limit时会不准确。(为毛?)


Extra

mysql查询的附加信息。



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

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

Select类型:

simplequery中不包含子查询或联合查询。

primary:包含子查询或联合查询的query中,最外层的select查询。

subquery:子查询在select的目标里,不在from,子查询的第一个select

dependent subquery:子查询内层的第一个select,依赖于外部查询的结果集。

uncacheable subquery:表示子查询,但返回结果不能被cache,必须依据外层查询重新计算。

derived:子查询在from子句中,执行查询的时候会把子查询的结果集放到临时表(衍生表)

union:在联合查询中第二个及其以后的select对应的类型。

union result:从union临时表获取结果集合。例如上面两个查询结果集中的最后一行。

dependent union:子查询中的union,且为union中第二个select开始的后面所有select,同样依赖于外部查询

的结果集。

uncacheable union:表示union第二个或以后的select,但结果不能被cache,必须依据外层查询重新计算。

Type类型:

nullmysql在优化过程中分解query,执行时甚至不用再访问表数据或者索引,比如id=-1

const:最多会有一条记录匹配。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快

,因为它们只读取一次。发生在有一个unique key或者主键,并且where子句给它设定了一个比较值。

eq_ref:使用这种索引查找,最多返回一条符合条件的记录。会在使用主键或者唯一性索引访问数据时看到,

除了const类型这可能是最好的联接类型。

ref:这是一种索引访问。只有当使用一个非唯一性索引或者唯一性索引的非唯一性前缀(换句话说,就是无法

根据该值只取得一条记录)时才会发生,将索引和某个值相比较,这个值可能是一个常数,也可能是来自前一个

表里的多表查询的结果值。如果使用的键仅仅匹配少量行,该联接类型是不错的。

ref_or_null:类似ref。不同的是Mysql会在检索的时候额外的搜索包含 NULL 值的记录,他意味着mysql必须

进行二次查找,在初次查找的结果中找出NULL条目。

index_merge:查询中使用两个或多个索引,然后对索引结果进行合并。在这种情况下,key列包含所有使用的

索引,key_len包含这些索引的最长的关键元素。

unique_subquery:用来优化有子查询的in,并且该子查询是通过一个unique key选择的。子查询返回的字段组

合是主键或者唯一索引。

index_subquery:该联接类型类似于unique_subquery,子查询中的返回结果字段组合是一个索引或索引组合,

但不是一个主键或者唯一索引。

一定范围内扫描索引。如where中带有between或者>,此时ref列为NULL。当使用=<>>>=<<=IS 

NULL<=>BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range

index:按索引次序扫描数据。因为按照索引扫描所以会避免排序,但也会扫描整表数据,若随机读取开销会更

大。如果extra列显示using index,说明使用的是覆盖索引(覆盖索引:包含所有满足查询需要的数据列的索引

)。对于InnoDB表特别有用,此时只访问索引数据即可,不用再根据主键信息获取原数据行,避免了二次查询,

MyISAM表优化效果相对InnoDB来说没有那么的明显。

all:按行扫描全表数据,除非查询中有limit或者extra列显示使用了distinctnotexists等限定词。