您的位置:首页 > 数据库 > MySQL

七进七出Mysql之Mysql的执行计划(EXPLAIN)

2019-03-05 19:06 183 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/yuliang123345/article/details/88063639

大家好,我叫于国富,今天我来给大家通俗易懂的讲解下Mysql的执行计划。

一、什么是执行计划(EXPLAIN)

          我就以我个人的理解,给大家说一下,太专业的我也不会也懒得去抄别人的。执行一条Sql,你能感知到的只有Sql运行时间和执行结果,感知不到的是数据库里实际发生了什么事情,比如我们不知道数据库是怎么样扫描表数据的、用没用到索引、索引用的是否是最优的等。如果想要知道这些信息,这个时候explain就起到了很大的作用,它可以用来查看我们不知道的那些信息。

 

二、EXPLAIN参数详解

Mysql执行计划的使用,就是在Sql前加一个"EXPLAIN"即可,如下:

执行效果如下:

好的,Ladies and  乡亲们现在就到了给大家讲解具体参数的环节了,请大家有条件的拿小本本记下来,没条件的多看几遍。

1、Id列

我的理解是Sql子查询执行的顺序,分为四种情况:

    第一种为Id值越大,则表示越先被执行

    第二种是Id值相同,则执行顺序为由上至下

   第三种是既有Id值相同的又有Id值不同的,如果Id值相同的大于Id值不同的,则先执行Id值相同的,执行顺序是由上到下,然后执行Id值不同的

第四种id为null时表示一个结果集,不需要使用它查询,常出现在包含union等查询语句中。

2、select_type列

每个子查询的查询类型,常见的查询类型如下:

id select_type description
1 SIMPLE 不包含任何子查询或union等查询
2 PRIMARY 包含子查询最外层查询就显示为 PRIMARY
3 SUBQUERY 在select或 where字句中包含的查询
4 DERIVED from字句中包含的查询
5 UNION 出现在union后的查询语句中
6 UNION RESULT 从UNION中获取结果集

3、table列

其实就是每个子查询涉及的表,或者说是每个子查询检索的是哪个表的数据。

4、partitions列

这个参数涉及到数据库表分区(partitions)这个概念,讲起来比较复杂,在这里就不细讲了,想要了解可查看以下这个链接https://www.geek-share.com/detail/2671382613.html,我只给大家举个简单的通过Key分区的例子,如下:

5、type列

这个参数就厉害了,有人叫它连接类型,但它又不是多个表连接的意思,官方点说是一种数据库引擎查找表的一种方式。按我的理解就是通过这个参数我们能知道Mysql是通过那种方式来访问所需要的数据行,所以我觉得叫访问类型比较合适。常出现的类型有六种,从左到右,查询性能依次增加,分别为:ALL,index,range,ref,eq_ref,const。以下我分别给大家详细讲解下

ALL类型

这个类型就是所谓的全表扫描,如果你是想查询表的所有数据,这个类型倒是没有什么问题。但是如果只查询一部分数据,那它就说明你这个子查询有问题,没有用到任何的优化手段,你就需要重新审查你这条Sql语句,或者为表添加合适的索引。

index类型

这个类型官方说是扫描全部索引树时会出现,我不是很理解,所以我查找资料并亲身测试了,发现只有两种检索数据的时候会出现,一种是只查询有索引的字段的时候会出现,还有一种是使用order by 主键的时候会出现,如下:

1)

2)

range类型

这个类型说的就是有范围的索引扫描,简单来说就是包含between、<、>的Sql查询语句,前提是查询条件一定是已经添加了索引的字段。

ref类型

当使用添加了索引的字段当查询条件,并且该索引既不是主键索引又不是唯一索引的时候会出现该类型。这个类型很常见,我觉得一条好的Sql,最差也得是这个类型的。

eq_ref类型

与ref类型类似,区别在于ref类型使用的是非主键和非唯一的索引,而eq_ref与之恰恰相反,它只有使用主键或者唯一索引当查询条件的时候才会出现这种类型。

 

const类型

这个类型就好理解了,使用主键或者唯一索引,且匹配的结果只有一条记录,如下:

6、tpossible_keys

查询涉及到的字段若存在索引,则该索引将被列出来,但是实际不一定被查询使用。当该列为 NULL时就要考虑是否需要为当前Sql涉及到的查询条件字段添加索引,或者是否需要优化Sql。

7、key

这一列其实是显示Mysql实际决定需要使用的索引,Mysql会把这条Sql实际用的索引都显示在这个列上,这个列tpossible_keys列的关系是包含与被包含的关系。其实也是可以强制Mysql使用tpossible_keys列的索引的,只需要在查询使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

8、key_len

这一列显示的是Mysql决定使用索引的长度,该列显示的值为索引字段的最大可能长度,并非实际使用长度。我了解到其实每种数据类型都是有计算使用长度的公式,这里就不一一讲解了,有想知道的可以自行百度。还有就是不损失精确性的情况下,长度越短越好 。

9、ref

如果是使用的常数等值查询,这列会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func。

const

关联字段

func

不好意思各位,我没复现出来,嘿嘿!

10、rows

该列里的值,就是Mysql扫描了多少行数据才得到的你想要的查询结果数据,一般情况下,扫描的行数会大于你想要的查询结果行数,这个列的值,越小说明你的Sql查询效率越高,其实优化Sql就是在减少该列的值。

11、filtered

该列指示将按表条件筛选的表行的估计百分比。 最大值为100,这意味着不会对行进行过滤。 值从100开始减少表示过滤量增加。 rows列显示已检查的估计行数,rows×filtered显示将与下表连接的行数。 例如,如果rows列值为1000且filtered列过滤为50.00(50%),则使用下表连接的行数为1000×50%= 500。

 

12、Extra

其实这些列中只有这一列是最让人难以琢磨的,我理解这个列就相当于是个备注,针对Mysql解析查询语句,其他列没有提供的详细信息,都会在这一列显示。以下我说几个常见的:

id extra description
1 NULL 一般这种情况下没有where条件,直接做全表扫描得到sql执行结果
2 Using where where的列为非索引列,通过使用全表扫描,然后再使用where条件去过滤行.
3 Using index condition 表示使用索引条件去读取表中的数据,先扫描索引,然后根据索引指向的主健去读取对应的数据
4 Using filesort 表示语句中有排序操作
5 Using temporary 表示使用了临时表或是文件来排取,一般出现在group by,distinct和集合操作语句中
6 Impossible where 出现在优化阶段,优化器根据表定义可以判断出where条件根本不可能成立,比如主健不可能为空
7 Using join buffer (Block Nested Loop) mysql使用了优化过的nest loop算法,一次读取多个块

Extra这一列,我觉得可参考大神整理的这篇博客:https://www.cnblogs.com/StanleyBlogs/p/10429969.html,讲解的很仔细。

 

三、总结

1、当你优化Sql的时候感觉无从下手,那一定要学会使用Mysql的执行计划

2、Mysql的执行计划是与索引密切相关的,在学习之前可以先多了解了解Mysql索引相关的知识

3、其实我觉得执行计划这十二个列中,type列、possible_keys列、key列还有rows列是比较重要的

4、Mysql的执行计划就像一面照妖镜,Sql是好是坏,一照便知

 

(注:文章中部分有借鉴,但是添加了自己的理解。第一次整理,不好的地方还请多多担待,给各位爷鞠躬了!)

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: