explain mysql执行顺序_「explain」MySQL系列-优化之explain执行计划详解 - seo实验室

explain

1.id介绍

这个id不是主键的意思,他是用来标识select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序。

会出现以下情况:

id相同:按从上到下顺序执行

id不同:id值越大,优先级越高,越先被执行

id相同不同的同时存在:优先执行id值大的,如果id值相同,则按从上到下的顺序执行

id为null表示是用来合并结果集的,在sql使用union关键字合并结果集就会出现他。

2.select_type介绍

顾名思义,表示查询的类型

类型

说明simple

简单子查询,不包含子查询和union

primary

包含union或者子查询,最外层的部分标记为primary

subquery

一般子查询中的子查询被标记为subquery,也就是位于select列表中的查询

derived

派生表——该临时表是从子查询派生出来的,位于form中的子查询

union

位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是union位于from中则标记为derived

union result

用来从匿名临时表里检索结果的select被标记为union result

dependent union

顾名思义,首先需要满足UNION的条件,及UNION中第二个以及后面的SELECT语句,同时该语句依赖外部的查询

subquery

子查询中第一个SELECT语句

dependent subquery

和DEPENDENT UNION相对UNION一样

3.table介绍

对应行正在访问哪一个表,表名或者别名。也有可能是临时表等等,或者是union合并结果集。

表名是derivedN的形式,表示使用了id为N的查询产生的衍生表

当有union result的时候,表名是union n1,n2等的形式,n1,n2表示参与union的id

注意:mysql对待这些表和普通表一样,但是这些“临时表”是没有任何索引的。

4.举例说明

2018070715524796.png

说明:可以看到,先查询b2表再查询b1表,而且都是简单查询。

20180707155651966.png

说明:b2表对应的id为2,所以先查询b2表,查询类型是依赖子查询,然后在查询b1表,查询类型是主查询。

20180707160619213.png

说明:先查询b2表,在查询b3表,然后查询b1表,最后合并结果集。指的是将id为1和id为2查询的结果合并。

20180707172614894.png

说明:先查询b1表得出一个临时表,然后在查询这个临时表,这个derived2表示使用了id为2的查询出来的结果集作为临时表,最后才是b2表。

5.type介绍

type意味着类型,这里的type官方全称是“join type”,意思是“连接类型”,这样很容易给人一种错觉觉得必须需要俩个表以上才有连接类型,称之为访问类型更加容易理解。访问类型表示我们是以何种方式去访问我们的数据的,当然很容易想的的是全表扫描了,直接暴力的遍历一张表取寻找需要的数据,效率非常之低下。访问类型的种类有很多,而且各个版本的MySQL可能会不一样,但是常见的就那么几种,按照效率最差到最好依次排列依次是:

all < index < range < index_subquery < unique_subquery < index_merge < ref_or_null < ref < eq_ref < const

all : 这个就是全表扫描了,一般这样的出现这样的SQL而且数据量比较大的话那么就需要进行优化了,要么是这条SQL没有用上索引,要么是没有建立合适的索引。

index : 全索引扫描,这个比all效率要好一点,主要有几种情况,一是当前的查询是覆盖索引的,即我们需要的数据在索引中就可以获取(Extra中有Using Index,Extra也是explain的一个字段)(关于覆盖索引:MySQL系列-优化之覆盖索引),或者是使用了索引进行排序,这样就避免数据的重排序(extra中无 Using Index)。如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思。

range : 这个是index了范围限制,例如 >100、<1000之类的查询条件,这样避免的index的全索引扫描,当然限制的范围越小 效率就越高。

index_subquery : 在 某 些 IN 查 询 中 使 用 此 种 类 型 , 与 unique_subquery 类似,但是查询的是非唯一 性索引

unique_subquery : 在某些 IN 查询中使用此种类型,而不是常规的 ref

index_merge : 说明索引合并优化被使用了

ref_or_null : 如同 ref, 但是 MySQL 必须在初次查找的结果 里找出 null 条目,然后进行二次查找。

ref : 使用了非唯一性索引进行数据的查找,例如:我们对用户表的用户名这一列建立了非唯一索引,因为用户名可以重复,当我们查找用户的时候select * from user where username=“xxx”的时候就出现了ref,使用非唯一索引查找数据。

eq_ref : 这个就很好理解了,使用的唯一性索引进行数据查找,例如主键索引之类的。

const : 通常情况下,将一个主键放置到where后面作为条件查询,mysql优化器就能把这次查询优化转化为一个常量,如何转化以及何时转化,这个取决于优化器。这个比eq_ref效率高一点。

system : 表只有一行。不过这种情况下就没意义了。

NULL : MySQL不用访问表或者索引就直接能到结果。

6.举例说明

20180714131121429.png

可以看到,有三个字段,其中id是主键索引,n1是非唯一索引,n2是唯一索引。

20180714131514424.png

select * from tb1; 简单粗暴的全表扫描

20180714131933355.png

查询数据n1的时候使用了覆盖索引。

20180714132212950.png

使用n1列的索引进行排序,所以extra中没有出现using index,因为当前查询不是索引覆盖的。这里我强制使用了idx_n1,MySQL也遵循了我的建议(如果强制使用的索引是用不上的话,MySQL会忽略)。

20180714132831195.png

很明显,id>3,只需要范围扫描。

20180714133048923.png

n1是非唯一索引,所以type为ref。

20180714133252472.png

n2这一列是唯一索引,MySQL直接把他优化到了const级别。

接下来的就不列举了,因为在开发中能优化到range就很不错了,而且有些情况因为业务的关系根本就不能优化。

7.possible_keys介绍

这个显示可能用到的索引,一个列上可能有多个复合索引,但最后只能选择其中一个使用。当然很可能一个都不会使用,也可能显示没有可能用上的索引,但最后却用上了某个索引,所以这个possible_keys没什么太大意义。

8.key

这个就真实的反应了MySQL使用了哪个索引。这个字段很关键,因为MySQL优化器的能力有限,有时候他使用的索引不一定是最优的,所以我们需要知道他到底使用了那个索引,以及强制MySQL使用某个DBA认为最优的索引。当然如果当前的查询是覆盖索引的话,这个索引也会出现在key中。

9.key_len介绍

他表示索引中使用的字节数,可通过该key_len计算查询中使用的索引长度,当然在不损失精度的情况下长度越短越好。但是这个key_len只是表示使用索引的长度最大可能是多少,并不是真实的长度。

10.举例说明

20180714141723395.png

对n1和n2字段建立一个复合索引

20180714142024451.png

可以看到,possible_key是null,实际使用了索引idx_n1n2,索引长度为1536,并且是覆盖索引。

那如果我们强制使用索引idx_n1呢?

20180714142409758.png

可以看到,key_len变短了,同时也从覆盖索引变成了非覆盖索引。

11.ref介绍

显示索引的哪一列被使用了,如果可能的话,是一个常数。

12.rows介绍

根据表的统计信息及索引使用情况,大致估算出找出所需的记录需要读取的行数。这个rows非常重要,直接反应的SQL找了多少数据,从前面的举例说明中我们也可以看到,在完成目的的情况下当然是越少越好。这个更SQL使用的索引息息相关,可见索引的重要性。

13.extra介绍

这个是包含了一些十分重要的额外信息,也是非常重要的一个字段。

他可能包含以下一个或多个值:

1、using filesort,这个说明mysql无法利用索引进行排序,那他只能用排序算法重新进行排序了,这会额外消耗资源。出现这个的话那么说明这条SQL需要优化了,需要正确使用索引或者建立合适的索引。

下面是一个让MySQL使用正确索引的例子,同样的结果,不一样的过程。

但是具体那条SQL更快呢,也不一定,根据具体情况而定,比如数据规模之类的。还有就是开发当中一般是不允许用select * 的,要什么字段就拿什么字段,不然会造成性能浪费。

20180714161135819.png

2、using temporary,建立了临时表来保存中间结果,查询完成之后又要把临时表删除。出现这样的情况说明这条SQL语句请一定要优化,如果这样的SQL一多的话非常影响系统的性能。

3、using index,前面也说过,这个表示当前的查询是覆盖索引的,直接从索引中读取数据,而不用访问数据表。如果同时出现using where表明索引被用来执行索引键值的查找,如果没有using where,表面索引被用来读取数据,而不是进行查找。

4、using where,使用了where进行条件过滤。

5、using join buffer、表示使用了连接缓存。

6、impossible where,where语句的值总是false。

7、Distinct,一旦MySQL找到了与行相联合匹配的行,就不再搜索了。

14.重点

type:访问类型,查看SQL到底是以何种类型访问数据的。

key:使用的索引,MySQL用了哪个索引,有时候MySQL用的索引不是最好的,需要force index()。

rows:最大扫描的列数。

extra:重要的额外信息,特别注意损耗性能的两个情况,using filesort和using temporary。

参考资料:

MySQL explain详解

谷粒学院

mysql explain type连接类型示例

相关阅读

回归分析方法想要资源的请关注公众号: 在一起的足球自动获取资源和数十种经典算法,帮助各位提升自己之前留的是自己的qq号 感觉好多

提示:本文的源码均取自Android 7.0

前言

在平时的开发过程中,我们一般是通过XML文件去定义布局,所以对于LayoutParams的使用可能

Android布局控件之LinearLayout详解

LinearLayout是线性布局控件,

(2019年7月22日,上海)企业战略转型,尤其是海外扩张之际,第一个要匹配的就是人才战略计划,企业整体英语能力的培养往往会被一举提升到战

一个JSP页面有多个客户访问,下面是第一个客户访问JSP页面时候,JSP页面的执行流程:

1,客户通过浏览器向服务器端的JSP页面发送请求

2,JS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值