一、EXPLAIN介绍

MySql提供了EXPLAIN语法用来进行查询分析,在SQL语句前加一个"EXPLAIN"即可。比如我们要分析如下SQL语句:

explain select * from table where table.id = 1

运行上面的sql语句后你会看到,下面的表头信息:

table | type | possible_keys | key | key_len | ref | rows | Extra

二、EXPLAIN列的解释

在mysql命令行中,执行explain命令可以看到sql执行计划

ID:

包含一组数字,表示查询中执行select子句或操作表的顺序,id相同,可以认为是一组,执行顺序由上至下,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

select_type:

表示查询中每个select子句的类型(简单 、复杂)

SIMPLE:查询中不包含子查询或者UNION

PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY

SUBQUERY:在SELECT或WHERE列表中包含了子查询,该子查询被标记为SUBQUERY

DERIVED:在FROM列表中包含的子查询被标记为DERIVED(衍生)。若UNION包含在  FROM子句的子查询中,外层SELECT将被标记为DERIVED

UNION:若第二个SELECT出现在UNION之后,则被标记为UNION

UNION RESULT:从UNION表获取结果的SELECT被标记为UNION RESULT

table:

输出的行所引用的表

type:

表示MySQL在表中找到所需行的方式,又称“访问类型”

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index:Full Index Scan,index与ALL区别为index类型只遍历索引树

range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between、<、>等的查询

ref:非唯一性索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引即唯一索引的非唯一前缀进行的查找

eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描

const、system:当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量。system是const类型的特例,当查询的表只有一行的情况下, 使用system

NULL:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引

possible_keys:

指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。

key:

显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL。查询中若使用了覆盖索引,则该索引仅出现在key列表中。

key_len:

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。

ref:

显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:

表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数。

Extra:

关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢

说明:extra列返回的描述的意义

Distinct :一旦mysql找到了与行相联合匹配的行,就不再搜索了。

Not exists :mysql优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了。

Range checked for each Record(index map:#) :没有找到理想的索引,因此对从前面表中来的每一个行组合,mysql检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一。

Using filesort :看到这个的时候,查询就需要优化了。mysql需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。

Using index :列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候。

Using temporary :看到这个的时候,查询需要优化了。这里,mysql需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上。

Where used :使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题。