Mysql 中explain命令 的使用

September 13, 2016 10:19 AM

声明

文章内容出自《高性能Mysql第三版》

explain只是一个近似值,有以下限制

  1. explain根本不会告诉你触发器,存储过程或者UDF会如何影响查询
  2. 不支持存储过程,可以手动抽取查询并explain
  3. 并不会告诉你MySQL在查询中执行所做的特定优化
  4. 并不会显示关于查询的执行的所有信息
  5. 并不区分具有相同名字的事物。例如不管是内存排序还是文件排序都是filesort,内存的临时表和磁盘的临时表都为using temporary
  6. 可能误导。他会对一个有着很小的limit的查询显示全索引扫描

explain结果列说明

select_type: 显示了对应列是简单还是复杂的select

  1. subquery:包换在select列表中的子查询的select(换句话就是不在from字句中)中标记为subquery
  2. derived:用来表示包含在from字句的子查询中的select
  3. union:在union中的第二个和随后的select被标记为union,如果union被from字句中的子查询包含,那那她的第一个select就会被标记为derived
  4. union result:用来从union的匿名临时表检索结果的select被标记为union result
  5. simple : 简单查询,不包含子查询和unio

table: 表示对应行访问那个表

但是如果有子查询或者union。那么将会很复杂,这时候子查询就会显示为derivedN,其中N是查询的ID。当为union时,union result的table列包含一个参与union的ID列表

type: 官方显示为‘关联类型’,但我们认为最准确的说法为访问类型

  1. All : 全表扫描
  2. index : 这个给 全表扫描一样。只不过MySQL扫描表示按索引的次序进行而不是行。他的主要优点是避免了排序;最大的缺点是要承担按索引次序读取整个表的开销。如果在Extra列中看到Using index;说明MySQL正在使用覆盖索引,这样的话效率会高很多
  3. range : 范围扫描,比全表扫描好一些
  4. ref:索引查找,它会返回所有匹配某个单个值的行。然而,它可能会查找到多个符合条件的行,因此,它是查找和扫描的混合体。此类索引访问只有当使用非唯一索引或者唯一索引的非唯一性前缀才会发生。 ref_or_null是ref的一个变体。意味着MySQL必须在初次查找的结果里进行第二次查找以找出null条目
  5. eq_ref : 只返回一条符合条件的记录,在使用唯一索引或者主键的时候会看到
  6. cont,system : 当查询的某个部分进行优化并将其转换为一个常量是,他就会出现使用这些访问类型。实例:将一行的主键放入where字句里的方式来选取此行的主键。MySQL就会把覆盖查询转换为一个常量。然后就可以高效地从联接执行中移除
  7. Null : mysql能在优化阶段分解查询语句,在执行阶段甚至用不着在访问表或者索引

possible_keys: 显示了查询可以使用那些索引。 key: 显示了使用了那些索引。如果该索引没有出现在possible_key中,那么MySQL选取他是出于其他原因,比如选择了一个覆盖索引。 key_len: 索引里使用的字节数. ref: 显示了之前的表在key记录的索引中查找值所用的列或常量。 rows: 估计为了找到所需要的行而要读取的行数。这个数字是内嵌循环关联计划里的循环数目。 Extra: 这一列包含的是不适合在其他列显示的额外信息。

  • Using index :使用了覆盖索引
  • Using where:服务器将在存储引擎检索行后在进行过滤。
  • Using temporary:使用了临时表
  • Using filesort:这意味着会对结果使用一个外部索引排序,而不是按索引的次序从表里读取行。
  • Range checked for each record(index map:N):没有好用的索引,行的索引将在链接的每一行上重新估算,N显示在possible_key列中索引的位图,并且是冗余的。