mysql最新版explain详解来自官网直译(2)

来源:互联网 发布:windows怎么更新系统 编辑:程序博客网 时间:2024/06/11 21:19
explain输出信息详解
id(JSON name:select_id): 这是select执行查询的顺序号。这个值也可以是null,当输出行引用的是其他行结果的合集时。在这种情况下,输出行的table这一列将会是一个类似于<unionM,N>的值,表示这一行引用来自行id为M和N的结合。
select_type(JSON name:none):查询的类型,下面表格中展示的类型都可以出现在这一列中。而对于JSON格式的输出,查询类型将会作为一个query_block属性展示,除非他是simple或者primary。关于JSON names也展示在表格中
select_type 值      JSON Name   意义
SIMPLE None 简单查询(没有使用union或者子查询)
PRIMARY None    最外层的查询
UNION None   union查询中的第二个或者之后的查询
DEPENDENT UNION dependent(true) union查询中的第二个或者之后的查询,且依赖于外部查询
UNION RESULT union_result union的结果
SUBQUERY None    子查询中的第一个查询
DEPENDENT SUBQUERY  dependent(true)   第一个依赖于外部查询的子查询
DERIVED None Derived table(派生表)的查询(在from条件句中的子查询)
MATERIALIZED   materialized_from_subquery  Materialized 子查询(物化查询)
UNCACHEABLE            cacheable(false)   一个子查询的结果集无法缓存,必须在外部查询中再次评估每一行
 SUBQUERY
UNCACHEABLE   cacheable(false)            在union查询中的第二个或者之后的查询是一个不能缓存的子查询
 UNION


DEPENDENT通常意味着使用了正确的子查询 具体请看13.2.10.7的相关的子查询
DEPENDENT SUBQUERY 的评估和UNCACHEABLE SUBQUERY不同。对于DEPENDENT SUBQUERY,子查询的重复评估只有一次,那就是每一个集合中的值对于外部语境来说意味着不确定性。对于UNCACHEABLE SUBQUERY,子查询需要重复评估对于外部语境的每一行数据。
对应查询缓存来说,可缓存的子查询不同于缓存查询结果的查询(具体的描述请看8.10.3.1的怎样操作查询缓存)。子查询的缓存发生在查询执行过程中,而查询缓存是当查询执行完成以后被用来缓存结果的。
当你给EXPLAIN设置了FORMAT=JSON,那么在输出中并没有单一的属性直接和select_type相等;而是一个query_block属性给出了查询。对于子查询的类型的等价属性列也可以适当的被展示(例如对应于MATERIALIZED的meterialized_from_subquery)。但是对于simple或者是primary没有对应等价的JSON。
对于非查询类型的执行计划,select_type的值展示的影响表的执行类型,例如对于删除操作,则select_type是DELETE。


table(JSON name:table_name):对于该列的输出,可能是以下一些值:
<unionM,N> :行的引用来自id值是M和N的行的结合union
<derivedN> :行的引用来自id值为N的派生表的结果。而派生表可能来自一个在from之后的条件子查询。
<subqueryN>:行的引用来自id值为N的物化子查询的结果。具体请看8.2.2.2的优化物化子查询。
partitions(JSON name:partitions):分区来自通过查询匹配的记录。对于没有分区的表,该值为null。更多信息请参考官方文档的22.3.5的获取分区信息
type(JSON name:access_type):连接类型,对于不同类型的描述,请看explain的join Types.
possible_keys(JSON name:possible_keys):该列展示的索引来自mysql能够在该行展示的表中可以选择和找到的索引。该列是完全独立于表顺序被展示在Explain的输出中。也就是说一些索引有可能在实际生成表的顺序和查询时并没有使用。
如果这一列是null(对于json来说是未定义),则没有相关的索引。在这种情况下,你通常可以通过检查WHERE条件中的列是否有些可以走索引来提高查询效率。如果可以,则创建一个合适的索引,并再次检查explain中的查询。可以看13.8.1的修改表的语法。要想查看表中有哪些索引,可以通过命令show index from table_name。
key(JSON name:key):该列的值表明了mysql实际上使用的索引。如果mysql使用了possible_keys索引集中的某一个索引来查找行,则该索引就会是key列对应的值。
当然key中索引的名字也有可能并不在possible_keys中,如果在possible_keys中的索引值都不适合用来查找行数据,但是通过其他列的索引依然可以选择出想要的结果集。也就是索引列覆盖了要查询的列,所以尽管该索引不能决定那些行数据被统计,但是索引扫描绝对比整行数据扫描更有效。
对于innoDB数据库,一个二级索引也许覆盖了要查询的列,即使是查询也选择了主键,因为innoDB通过二级索引来存储主键索引(覆盖索引通过二级索引来实现)对应的值。如果key是null,mysql发现没有索引能够用于查询来提高效率。
对于myisam表,通过运行命令ANALYZE TABLEB帮助优化器选择更好的索引。myisamchk --analyze有同样的效果。
key_len(JSON name:key_length):该列说明了mysql决定使用的索引的长度。key_len的值可以告述你mysql实际使用的联合索引(multiple-part key)中的哪些部分。如果key列的值为null,则该列的值也为null.
因为索引的存储格式,对于null列的存储比非null值的存储更占空间。
ref(JSON name:ref):ref列说明了哪些列或者是常量被用于和key列中用到的索引去对比来选择表中的行集。如果其中的值为func,则使用的是一些函数的结果。如果想看是那些function,使用SHOW WARNINGS跟着explain来扩展explain的输出。函数实际上有可能是一个操作,比方说计算操作。
rows(JSON name:rows):该列的值说明了mysql觉得要执行查询必须要检查的行数。对于innodb中的表,这个数是一个预估值,并不是真实值。
filtered(JSON name:filtered):说明了通过表条件过滤掉的表中行数的占比。也就是说,估计会有rows*filtered/100的行数需要于之前的表去检查对比。
Extra(JSON name:none):该列包含了关于mysql解析查询的额外信息。对于不同值的详解将会在之后说明。
没有简单的JSON属性列于Extra列等价。然而,关于这一列的值可以被展示作为JSON的属性,或者是message属性的文本。
到此表中的全部列基本上就介绍完了,然后接下来要说明的就是对JOIN TYPES的说明,对Extra信息的详细说明,和Explain输出的举例说明。
原创粉丝点击