Mysql执行计划Explain详解(一)

为什么要使用 explain?

explain 可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们查询,让查询优化器能够更好的工作。

EXPLAIN 的每个输出行提供一个表的相关信息,并且每个行包括下面的列

Explain

id

MySQL Query Optimizer 选定的执行计划中查询的序列号。表示查询中执行 select 子句或操作表的顺序,id 值越大优先级越高,越先被执行。id 相同,执行顺序由上至下。

select_type 查询类型

  1. SIMPLE 简单的 select 查询,不使用 union 及子查询
  2. PRIMARY 最外层的select 查询
  3. UNION UNION中 的第二个或随后的select 查询,不依赖于外部查询的结果集。
  4. DEPENDENT UNION UNION 中的第二个或随后的select查询,依赖于外部查询结果集。
  5. UNION RESULT UNION 查询的结果集
  6. SUBQUERY 子查询中的第一个select查询,不依赖于外部查询的结果集
  7. DEPENDENT SUBQUERY 子查询中的第一个select查询,依赖于外部查询的结果集
  8. * DERIVED* from子句里有子查询的情况。MySQL会递归执行这些子查询,把结果放在临时表里。
  9. UNCACHEABLE SUBQUERY 结果集不能被缓存的子查询没,必须重新为外层查询的每一行进行评估。
  10. UNCACHEABLE UNION UNION 中的第二个或随后的select查询,属于不可缓存的子查询。

table

输出行所引用的表

type 重要的项,显示连接使用的类型,按最优到最差的类型排序

  1. system 表仅有一行(=系统表)。这是const连接类型的一个特例
  2. const const用于用常数值比较PRIMARY KEY时。当查询的表仅有一行时,使用System.
  3. eq_ref 除const类型外最好的可能实现的连接类型。它用在一个索引的所有部分被连接使用并且索引是UNIQUE或PRIMARY KEY,对于每个索引键,表中只有一条记录与之匹配。
  4. ref 连接不能基于关键字选择单个行,可能查找到多个符合条件的行。叫做ref是因为索引要跟某个参考值相比较。这个参考值或者是一个常数,或者是来自一个表里的多表查询的结果值。
  5. ref_or_null 如同ref,但是MySQL必须在初次查找的结果里找到null条目,然后进行二次查找。
  6. index_merge 说明索引合并优化被使用了。
  7. unique_subquery 在某些IN查询中使用此种类型,而不是常规的ref :
    value IN (SELECT primary_key FROM single_table WHERE some_expr)
  8. index_subquery 在某些IN查询中使用此种类型,与unique_subquery类似,但是查询的是非唯一性索引 :value in (SELECT key_column FROM Single_table WHERE some_expr)
  9. range 只检索给定范围的行,使用一个索引来选择行。key列显示使用的哪个索引。当使用 =,<>,>,>=,<,<=,IS NULL,<=>,BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range。
  10. index 全表扫描,只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序,但是开销仍然非常大。
  11. all 最坏的情况,从头到尾全表扫描。

possible_keys

指出MySQL能在该表中使用哪些索引有助于查询。如果为空,说明没有可用的索引。

key

MySQL实际从possible_key选择使用的索引。如果为NULL,则没有使用索引。很少的情况下,MySQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX (indexname)来强制使用一个索引或者用 IGNORE INDEX(indexname)来强制MySQL忽略索引。

key_len

使用的索引的长度。在不损失精确性的情况下,长度越短越好。

ref

显示索引的哪一列被使用了。

rows

MySQL认为必须检查的用来返回请求数据的行数。

extra

extra 中出现以下 2 项意味着 MYSQL 根本不能使用索引,效率会受到重大影响。应尽可能对此进行优化
1. Using filesort 表示MySQL 会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容。可能在内存或者磁盘上进行排序。MySQL中无法利用索引完成的排序称为”文件排序“。
2. Using temporary 表示MySQL 在对查询结果排序时使用临时表。常见于排序order by 和分组查询 group by。

结束语

弄明白了 explain 语法返回的每一项结果,我们就能知道查询大致的运行时间了,如果查询里没有用到索引、或者需要扫描的行过多,那么可以感到明显的延迟。因此需要改变查询方式或者新建索引

猜你喜欢

转载自blog.csdn.net/bug4pie/article/details/79355923