标签:with 读取 而且 取数 xpl 避免 参数 strong 子查询
1.explain(执行计划)中涉及的各字段理解
1.1) select_type列的取值及含义:
SIMPLE :简单的SELECT语句(不包括UNION操作或子查询操作)
PRIMARY :查询中最外层的SELECT(如两表做UNION或者存在子查询的外层的表操作为PRIMARY,内层的操作为UNION)
UNION :UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句没有依赖关系)
DEPENDENT UNION :UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句有依赖关系)
UNION RESULT :UNION操作的结果,id值通常为NULL
SUBQUERY :子查询中首个SELECT(如果有多个子查询存在):
DEPENDENT SUBQUERY :子查询中首个SELECT,但依赖于外层的表(如果有多个子查询存在)
DERIVED :被驱动的SELECT子查询(子查询位于FROM子句)
MATERIALIZED :被物化的子查询
UNCACHEABLE SUBQUERY :对于外层的主表,子查询不可被物化,每次都需要计算(耗时操作),严重消耗性能
UNCACHEABLE UNION :UNION操作中,内层的不可被物化的子查询(类似于UNCACHEABLE SUBQUERY)
备注:DEPENDENT 取决于、从属物;
参看博文:https://www.cnblogs.com/danhuangpai/p/8475458.html
1.2)key列:表明的是这次查找中所用到的索引
1.3)rows列:是指这次查找数据所扫描的行数(这里可以先这样理解,但实际上是内循环的次数)
1.4)type列:全称(join type)连接类型
mysql5.7中type的类型达到了14种之多,这里只记录和理解最重要且经常遇见的六种类型,它们分别是all,index,range,ref,eq_ref,const从左到右,它们的效率依次是增强的
1.4.1) all :该列既不是主键也不是索引,因此只能采用全表扫描来查找目标
1.4.2) index:这种连接类型只是另外一种形式的全表扫描,只不过它的扫描顺序是按照索引的顺序。这种扫描根据索引然后回表取数据,和all相比,他们都是取得了全表的数据,而且index要先读索引而且要回表随机取数据,因此index不可能会比all快(取同一个表数据),但为什么官方的手册将它的效率说的比all好,唯一可能的原因在于,按照索引扫描全表的数据是有序的。这样一来,结果不同,也就没法比效率的问题了。如果一定要比效率,只需要获取这个表的数据并且排序便可以看出来谁比谁效率高了:
备注:当type为index,且extra列中的值为‘Using index’,那么称这种情况为 索引覆盖。索引列中已经包含了数据信息,因此无需回表取数据。
1.4.3) range :range指的是有范围的索引扫描,相对于index的全索引扫描,它有范围限制,因此要优于index。关于range比较容易理解,需要记住的是出现了range,则一定是基于索引的。同时除了显而易见的between,and以及‘>‘,‘<‘外,in和or也是索引范围扫描。
1.4.4) ref :出现该连接类型的条件是:查找条件列使用了索引而且不为主键和unique。其实,意思就是虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描。但它的好处是它并不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内扫描。例如:给用户表中名称建立索引后就是这种情况。表现为:type为ref 而 Extra 为 Using index condition
1.4.5) ref_eq:ref_eq 与 ref相比牛的地方是,它知道这种类型的查找结果集只有一个?什么情况下结果集只有一个呢!那便是使用了主键或者唯一性索引进行查找的情况,比如根据学号查找某一学校的一名同学,在没有查找前我们就知道结果一定只有一个,所以当我们首次查找到这个学号,便立即停止了查询。这种连接类型每次都进行着精确查询,无需过多的扫描,因此查找效率更高,当然列的唯一性是需要根据实际情况决定的。
1.4.6) const :通常情况下,如果将一个主键放置到where后面作为条件查询,mysql优化器就能把这次查询优化转化为一个常量。至于如何转化以及何时转化,这个取决于优化器。
参看博文:https://blog.csdn.net/dennis211/article/details/78170079
1.5)filtered列:
执行Mysql的explain extended的输出会比单纯的explain多一列filtered,但是MySQL 5.7之后缺省extended也会输出filtered
它指返回结果的行占需要读到的行(rows列的值)的百分比。按说filtered是个非常有用的值,因为对于join操作,前一个表的结果集大小直接影响了循环的次数。
1.6)extra列常见的取值:
1.6.1) Using filesort: 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
1.6.2) Using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候.Using index:所需数据只需在 Index 即可全部获得,不须要再到表中取数据。
1.6.3) Using index for group-by:数据访问和 Using index 一样,所需数据只须要读取索引,当Query 中使用GROUP BY或DISTINCT 子句时,如果分组字段也在索引中,Extra中的信息就会是 Using index for group-by。
1.6.4) Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
1.6.5) Using where:如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where 信息。
1.6.6) Using where with pushed condition:这是一个仅仅在 NDBCluster存储引擎中才会出现的信息,而且还须要通过打开 Condition Pushdown 优化功能才可能被使用。控制参数为 engine_condition_pushdown 。
1.6.7) Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通过收集到的统计信息判断出不可能存在结果。
1.6.8) Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释
(按照效率高低的顺序排序)
1.6.9) system 表只有一行:system表。这是const连接类型的特殊情况
1.6.10) const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待
1.6.11) eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用
1.6.12) ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。
这个类型严重依赖于根据索引匹配的记录多少—越少越好
1.6.13) range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况
1.6.14) index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)
1.6.15) ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免
参看博文:https://www.imooc.com/article/45142
标签:with 读取 而且 取数 xpl 避免 参数 strong 子查询
原文地址:https://www.cnblogs.com/jiarui-zjb/p/12203240.html