前言

  MySQL中的explain命令显示了mysql如何使用索引来处理select语句以及连接表。explain显示的信息可以帮助选择更好的索引和写出更优化的查询语句。

一、格式

  explain + select 语句;

  例如:explain select * from tb_student;

二、5.5和5.7版本explain的区别

  5.7之后的版本默认会有 partitions 和 filtered两列,但是5.5版本中是没有的,需要

    使用explain partitions select ……来显示带有partitions 的列,

    使用explain extended select ……来显示带有filtered的列。

  本文是基于5.5.54版本的。

三、explain的作用

  1.描述MySQL如何执行查询操作、执行顺序,使用到的索引,以及MySQL成功返回结果集需要执行的行数。

  2.可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们的查询,让查询优化器能够更好的工作

  查询优化器的作用:

  1.优化select 语句,分析哪些是常量表达式(例如id=1),以及分析哪些表达式可以直接转换成常量的

  2.对where条件进行简化和转换,如去掉无用条件,调整条件结构等

  3.读取涉及的表的统计信息,并计算分析(例如返回的行数,索引信息等),最终得出执行计划

四、执行计划(QEP)包含的信息

  

  id:标识符,表示执行顺序

  select _type:查询类型

  table:输出行所引用的表

  partitions:使用的哪个分区,需要结合表分区才可以看到

  type:表示按某种类型来查询,例如按照索引类型查找,按照范围查找。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和all

  possible_keys:可能用到的索引,保存的是索引名称,如果是多个索引的话,用逗号隔开

  key:实际用到的索引,保存的是索引名称,如果是多个索引的话,用逗号隔开

  key_len:表示本次查询中,所选择的索引长度有多少字节

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

  rows:显示mysql认为执行查询时必须要返回的行数

  filtered:通过过滤条件之后对比总数的百分比

  extra:额外的信息,例如:using file sort ,using where, using join buffer,using index等

五、执行计划中各个参数的详解

1.id

  表示select标识符,同时表明执行顺序,也就是说id是一个查询的序列号,查询序号即为sql语句执行的顺序。

  (1)当id值相同时,按从上到下的顺序执行

  (2)当id全部不同时,按id从大到小执行

  (3)当id部分不同时,先执行id大的,id相同的,按从上到下的顺序执行

2.select_type

  (1)simple:表示简单的select,没有union和子查询

  (2)primary:最外面的查询 或者 主查询,在有子查询的语句中,最外面的select查询就是primary

  (3)subquery:子查询

  (4)union:union语句的第二个或者说是后面那一个select

  (5)union result:union之后的结果

  (6)dependent unoin:unoin 中的第二个或随后的 select 查询,依赖于外部查询的结果集

  (7)dependent subquery:子查询中的第一个 select 查询,依赖于外部 查询的结果集

  (8)derived:衍生表(5.7版本中不存在这一个)

3.table

  通常是表名,或者表的别名,或者一个为查询产生临时表的标示符(如派生表、子查询、集合)

4.partitions

  使用的哪些分区(对于非分区表值为null),在5.5版本中需要加上explain partitions select .....

5.type

  (1)const:表中最多有一个匹配行,const用于比较primary key 或者unique索引。因为只匹配一行数据,所以很快

  (2)eq_ref:唯一性索引扫描,对于每个来自于前面的表的记录,从该表中读取唯一一行

  (3)ref:非唯一性索引扫描,对于每个来自于前面的表的记录,所有匹配的行从这张表取出

  (4)ref_or_null:类似于ref,但是可以搜索包含null值的行,例如:select * from student where address='xxx' or address is null,需要在address建立索引。

  (5)index_merge:查询语句用到了一张表的多个索引时,mysql会将多个索引合并到一起

  (6)range:按指定范围(如in、<、>、between and等,但是前提是此字段要建立索引)来检索,很常见。如:select * from student where id < 5,id上要有索引。

  (7)index:全”表“扫描,但是是在索引树中扫描,通常比ALL快,因为索引文件通常比数据文件小,index扫描是通过二叉树的方式扫描,而all是扫描物理表。(也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)。例如:select name from student,但name字段上需要建立索引,也就是查询的字段属于索引中的字段。

  (8)all:全表扫描,扫描完整的物理表,此时就需要优化了。

6.possible_keys

  指出 MySQL 能在该表中可能使用的索引,显示的是索引的名称,多个索引用逗号隔开,如果没有,则为null。

7.key

  MySQL决定实际用到的索引,显示的是索引的名称,多个索引用逗号隔开,如果没有,则为null

8.key_len

  当用到组合索引的时候判断索引是否完全用上。

  -------------------------------------------------------------------------------------------------------------------------------------------------------------------

  实例:假设student表中有id int,name char(20)  DEFAULT NULL,address varchar(20) DEFAULT NULL,remark varchar(20) NOT NULL 字段,建立的索引是 idx_address_remark(在address和remark上建立的组合索引)

  查询的sql是:select * from student where address='深圳' and remark='java coder',此时,执行计划中的key_len是 (20*3+1+2)+ (20*3+2)= 125,那么这个是怎么得来的呢?

  ) ,3表示utf8字符集占用3个字节,1表示MySQL需要1个字节表示null,2表示变长字段(varchar是变长的)。  

  假设drop掉刚刚建立的索引,新建索引 idx_name_address(在name和address上建立组合索引)

  查询的sql是:select * from student where name='xbq' and address='深圳',此时,执行计划中的key_len是 (20*3+1)+ (20*3+2)= 123,那么这个值是怎么得来的呢?

  解析:20表示建表的时候 char(20) ,3表示utf8字符集占用3个字节,1表示MySQL需要1个字节标识null,即 20*3+1,后面的同样的道理。

   -------------------------------------------------------------------------------------------------------------------------------------------------------------------

  key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。

  计算key_len的公式:

    varchr(10)变长字段且允许NULL    =  10 * ( character set:utf8=3,gbk=2,latin1=1) + 1(NULL) + 2(变长字段)

    varchr(10)变长字段且不允许NULL =  10 *( character set:utf8=3,gbk=2,latin1=1) + 2(变长字段)

    char(10)固定字段且允许NULL       =  10 * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)

    char(10)固定字段且不允许NULL    =  10 * ( character set:utf8=3,gbk=2,latin1=1)

9.ref

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

10.rows

  显示mysql认为执行查询时必须要返回的行数,可结合type和key分析,没有用上索引的情况下,会全表扫描。rows的值越小越好,说明检索的数据少

11.filtered

  给出了一个百分比的值,这个百分比值和rows列的值一起使用,可以估计出那些将要和执行计划中的前一个表(前一个表就是指id列的值比当前表的id小的表)进行连接的行的数目。

  这一列在5.5版本中,需要加上 explain extended select ....。

12.extra

  此字段显示一些额外的信息,但是此字段的部分值具有优化的参考意义。

  (1)using where:表示查询使用了where 语句来处理结果

  (2)using index:表示使用了覆盖索引。这个值重点强调了只需要使用索引就可以满足查询表的要求,不需要直接访问表数据。

  (3)using join buffer:这个值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进性能

  (4)using filesort:这是 order by 语句的结果。这可能是一个CPU密集型的过程。using filesort表示出现了文件内排序,表示很不好的现象,必须要优化,特别是大表,可以通过选择合适的索引来改进性能,用索引来为查询结果排序。

  (5)using temporary:mysql需要创建一张临时表来保存中间结果。 也就是说,需要先把数据放到临时表中,然后从临时表中获取需要的数据。出现这种临时表,也是必须需要优化的地方,特别是数据量大的情况。两个常见的原因是在来自不同表的列上使用了distinct,或者使用了不同的 order by 和 group by 列。

  

MySQL性能优化(四)-- MySQL explain详解的更多相关文章

  1. MySQL性能优化(四):SQL优化

    原文:MySQL性能优化(四):SQL优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ ...

  2. (转)MySQL性能调优my.cnf详解

    MySQL性能调优my.cnf详解 https://blog.linuxeye.cn/379.html http://blog.csdn.net/orichisonic/article/details ...

  3. mysql服务性能优化—my.cnf配置说明详解

    MYSQL服务器my.cnf配置文档详解硬件:内存16G [client]port = 3306socket = /data/3306/mysql.sock [mysql]no-auto-rehash ...

  4. MySQL性能优化,MySQL索引优化,order by优化,explain优化

    前言 今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化.下期文章讲讲MySQL慢查询日志,我们是依据慢查询日志来判断哪条SQL语句有问题,然后在进行优化,敬请期待MySQL慢查询日志篇 建表 ...

  5. MySQL性能调优my.cnf详解

    [client] port = 3306 socket = /tmp/mysql.sock [mysqld] port = 3306 socket = /tmp/mysql.sock basedir  ...

  6. Mysql性能优化四:分库,分区,分表,你们如何做?

    分库分区分表概念 分区 就是把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的 分表 就是把一张数据量很大的表按一定的规则分解成N个具有独立存储空间的实体表.系统读写时 ...

  7. MySQL性能优化:MySQL中的隐式转换造成的索引失效

    数据库优化是一个任重而道远的任务,想要做优化必须深入理解数据库的各种特性.在开发过程中我们经常会遇到一些原因很简单但造成的后果却很严重的疑难杂症,这类问题往往还不容易定位,排查费时费力最后发现是一个很 ...

  8. Mysql 性能优化4 mysql参数配置

    mysql 参数的介绍 大概450项参数,大多保持默认就可以了 错误的参数 崩溃,错误,运行缓慢. 参数最好在生产环境前配置好.最好不要在生产环境 中 直接配置,有可能不会立即生效,或者之前的数据和配 ...

  9. MYSQL性能优化之Mysql数据库监控

    监控对象 数据库可用性监控数据库进程或是端口存在并不意味着数据库就是可用的 也就是说登陆服务器,并且能正确执行mysql命令 数据库性能 QPS和DPS并发线程数量(同时执行sql语句的数量,不是连接 ...

  10. 【MySQL性能优化】MySQL常见SQL错误用法

    https://yq.aliyun.com/articles/72501?utm_content=m_14899

随机推荐

  1. LeetCode: Restore IP Addresses 解题报告

    Restore IP Addresses My Submissions Question Solution Given a string containing only digits, restore ...

  2. JAVA-JSP之include指令

    相关资料:<21天学通Java Web开发> 结果总结:1.包含的可以是一个HTML文件,也可以是一个文件文件,当然也可以是一个JSP文件.2.只有当被包含的文件执行完成后,JSP文件才会 ...

  3. 一款基于TweenMax.js的网页幻灯片

    之前介绍了好多网页幻灯片.今天给大家带来一款基于TweenMax.js的网页幻灯片.这款幻灯片以不规则的碎片百叶窗的形式切换.切换效果非常漂亮.一起看下效果图: 在线预览   源码下载 实现的代码. ...

  4. 一款纯css3实现的超炫动画背画特效

    之前为大家介绍了很多款由纯css3实现的特效.今天要再给大家带来一款纯css3实现的超炫动画背画特效.代码非常简单,没有引用任何其它js代码.css代码也不多.效果非常炫.一起看下效果图: 在线预览  ...

  5. SpringMVC @ModelAttribute 详解

    [@Controller]4 详解@ModelAttribute http://blog.sina.com.cn/s/blog_6d3c1ec601017q4p.html A.@ModelAttrib ...

  6. hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

    /** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...

  7. 给原型扩展一下tirm方法

    方便以后,直记录下来 <script type="text/javascript"> //给原型护展tirm方法 String.prototype.trim=funct ...

  8. MATLAB 安装使用libsvm详细步骤

    根据本文后面部分博友提出的在配置过程中出现的问题,其中需要特别强调的一点:整个过程,都是在 libsvm-3.12\matlab目录下操作的.如果这一点你忽视了,你不可能解决配置中报的Bug,即使重新 ...

  9. 【转】WCF入门教程四[WCF的配置文件]

    一.概述 配置也是WCF编程中的主要组成部分.在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址.服务用于 ...

  10. par函数usr参数-控制坐标系的范围

    在R语言中,会根据数据的范围自动计算x轴和y轴的范围,举个例子 比如绘制一个1到5的散点图:代码示例: plot(1:5, 1:5) 生成的图片如下: 从图片中我们可以看到,x轴的起始位置比1要小,终 ...