标签:决定 exp ima 前缀 条目 select 承担 merge 分解
这一列显示了对应行是简单还是复杂SELECT(如果是复杂SELECT,那么是三种复杂类型中的哪一种)。SIMPLE值意味着查询不包括子查询和UNION。如果查询有任何复杂的子部分,则最外层部分标记为PRIMARY,其他部分标记如下:
SUBQUERY:包含列表中的子查询中的SELECT
explain select * from role_permission where role_id = (select id from role where name=‘管理员‘);
DERIVED: DRIVED值用来表示包含在FROM字句的子查询的SELECT,MySQL会递归执行并将结果放到一个临时表中。服务器内部称其“派生表”,因为该临时表是从子查询中派生来的。
explain select role_id from (select * from role_permission) rp
UNION:UNION中第二个或后面的SELECT语句
explain select * from role_permission where role_id=28 union select * from role_permission;
UNION RESULT:用来从UNION的匿名临时表检索结果的SELECT被标记为UNION RESULT
这一列显示了对应行正在访问哪个表。可以在这一列从上往下观察MySQL的关联优化器为查询选择的关联顺序。可以从下面的查询中MySQL选择的关联顺序不同于语句中所指定的顺序。
EXPLAIN SELECT film_id FROM film INNER JOIN film_actor USING(film_id) INNER JOIN actor USING(actor_id);
MySQL的查询执行计划总是左侧深度优先树。如果把这个计划放倒就能按顺序读出叶子节点
MySQL决定如何查找表中的行。下面依次从最差到最优
ALL:全表扫描,以为着MySQL必须扫描整张表,从头到尾,去找到需要的行。(这里也有例外,例如在查询里使用了LIMIT,或者在Extra列中显示“Using distinct/not exists”)
index:这个跟全表扫描一样,只是MySQL扫描表时按索引次序进行而不是行。它的主要优点是避免了排序,最大的缺点是要承担按索引次序读取整个表的开销。这通常意味着若是按随机次序访问行,开销将会非常大。如果在Extra列中看到“Using index”,说明MySQL正在使用覆盖索引,它只扫描索引的数据,而不是按索引次序的每一行。它比按索引次序全表扫描的开销要少很多。
range: 范围扫描就是一个有限制的索引扫描,它开始于索引里的某一点,返回匹配这个值域的行。这比全索引扫描好一些,因为它用不着遍历全部索引。显而易见的范围扫描是带有BETWEEN或WHERE子句里带有">"的插叙。当MySQL使用索引去查找一系列值时,例如IN()和OR列表,也会显示为范围扫描。然而,这两者其实是相当不同的访问类型,在性能上有重要的差异。次类扫描的开销跟索引类型相当。
例如:doctor表的primary key 是ID
explain select * from doctor WHERE ID in(1,2,3);
explain select * from doctor WHERE hospital_id in(1,2,3);
explain select * from doctor WHERE ID BETWEEN 1 AND 3;
ref:这是一种索引访问(有时也叫作索引查找),它返回所有匹配摸个单个值的行。然而,它可能会找到多个符合条件的行,因此,它是查找和扫描的混合体。此类索引访问只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。把它叫做ref是因为索引要跟某个参数值相比较。这个参考值或者是一个常数,或者是来自多表查询前一个表里的结果值。ref_or_null是ref之上的一个变体,它意味着MySQL必须在初次查找的结果里进行第二次查找以找出NULL条目。
eq_ref:使用这种索引查找,MySQL知道最多只返回一条符合条件的记录。这种访问方法可以在MySQL使用主键或者唯一索引查找时看到,它会将它们与某个参数值做比较。MySQL对于这类访问类型的优化做的非常好,因为他知道无需估计匹配行的范围或在找到匹配行后再继续查找。
const,system:当MySQL能对查询的某部分进行优化并将其转换成一个常量时,它就会使用这些访问类型。如果你通过将某一行的主键放入WHERE子句里的方式来选取此行的主键,MySQL就能把这个查询转换为一个常量。然后就可以高效的将表从联接执行中删除
例如:表doctor的ID是主键
EXPLAIN select hospital_id from doctor WHERE ID=2;
EXPLAIN select ID, hospital_id from doctor WHERE ID=2;
EXPLAIN select ID from doctor WHERE ID=2;
NULL:这种访问方式意味着MySQL能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。
这一列显示了查询可以使用哪些索引,这是基于查询访问的列和使用的比较操作符来判断的。这个列表是在优化过程的早期创建的,因此有些罗列出来的索引可能对于后续优化过程时没用的。
这一列显示了MySQL决定采用哪个索引来优化对该表的访问。如果索引没有出现在"possible_keys"列中,那么MySQL选用它是处于另外的原因。--例如,它可能选择了一个覆盖索引,哪怕没有WHERE子句
这列显示了MySQL在索引里使用的字节数。
这一列显示了之前的表在key列记录的索引中查找值所用的列或常量。
这一列是MySQL估计为了找到所需的行而要读取的行数。这个数字是内嵌循环关联计划里的循环数目。也就是说它不是MySQL认为它最终从表里读取出来的行数,而是MySQL为了找到符合查询的每一点上标准的那些行而必须读取的行的平均数。
这个列在使用“EXPLAIN EXTENDED”时出现。它显示的是针对表里符合某个条件(WHERE子句或联接条件)的记录数的百分比所做的一个悲观估算,优化器只有在使用ALL、index、range、index_merge访问方法时才会用这一估算。
这一列包含的是不适合在其他列的额外信息。
"Using index" 表示MySQL将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
“Using where”这意味着MySQL服务器将在存储引擎检索行后再进行过滤。许多WHERE条件里涉及索引中的列,当它读取索引时,就能被存储引擎检验,因此不是所有带WHERE子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
“Using temporary”这意味着MySQL在对查询结果排序时会使用一个临时表。
“Using filesort”这意味着MySQL会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。
“Range checked for each record(index map:N)”这个值意味着没有好用的索引,新的索引将在联接的每一行上重新估算。N是显示在possible_keys列中索引的位图,并且是冗余的。
[1] Baron Schwartz等 著,宁海元等 译 ;《高性能MySQL》(第3版); 电子工业出版社 ,2013
[2] 博客,http://blog.csdn.net/zhuxineli/article/details/14455029
标签:决定 exp ima 前缀 条目 select 承担 merge 分解
原文地址:http://www.cnblogs.com/happyflyingpig/p/7725444.html