带你学习MySQL执行计划


Posted in MySQL onMay 31, 2021

1.执行计划简介

执行计划是指一条 SQL 语句在经过 MySQL 查询优化器的优化会后,具体的执行方式。MySQL 为我们提供了  EXPLAIN 语句,来获取执行计划的相关信息。需要注意的是,EXPLAIN 语句并不会真的去执行相关的语句,而是通过查询优化器对语句进行分析,找出最优的查询方案,并显示对应的信息。

执行计划通常用于 SQL 性能分析、优化等场景。通过 explain 的结果,可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引可以被命中、哪些索引实际会命中、每个数据表有多少行记录被查询等信息。

explain 执行计划支持 SELECT、DELETE、INSERT、REPLACE 以及 UPDATE 语句。我们一般多用于分析 select 查询语句。

2.执行计划实战

我们简单来看下一条查询语句的执行计划:

mysql> explain SELECT * FROM dept_emp WHERE emp_no IN (SELECT emp_no FROM dept_emp GROUP BY emp_no HAVING COUNT(emp_no)>1);
+----+-------------+----------+------------+-------+-----------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys   | key     | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+----------+------------+-------+-----------------+---------+---------+------+--------+----------+-------------+
|  1 | PRIMARY     | dept_emp | NULL       | ALL   | NULL            | NULL    | NULL    | NULL | 331143 |   100.00 | Using where |
|  2 | SUBQUERY    | dept_emp | NULL       | index | PRIMARY,dept_no | PRIMARY | 16      | NULL | 331143 |   100.00 | Using index |
+----+-------------+----------+------------+-------+-----------------+---------+---------+------+--------+----------+-------------+

可以看到,执行计划结果中共有 12 列,各列代表的含义总结如下表:

 

列名

含义

id

SELECT查询的序列标识符

select_type

SELECT关键字对应的查询类型

table

用到的表名

partitions

匹配的分区,对于未分区的表,值为 NULL

type

表的访问方法

possible_keys

可能用到的索引

key

实际用到的索引

key_len

所选索引的长度

ref

当使用索引等值查询时,与索引作比较的列或常量

rows

预计要读取的行数

filtered

按表条件过滤后,留存的记录数的百分比

Extra

附加信息

下面我们来看下执行计划中部分重要列详解:

id:

SELECT 标识符。这是查询中 SELECT 的序号。如果该行引用其他行的并集结果,则值可以为 NULL 。当 id 相同时,执行顺序 由上向下;当 id 不同时,id 值越大,优先级越高,越先执行。

select_type:

查询的类型,常见的值有:

  • SIMPLE:简单查询,不包含 UNION 或者子查询。
  • PRIMARY:查询中如果包含子查询或其他部分,外层的 SELECT 将被标记为 PRIMARY。
  • SUBQUERY:子查询中的第一个 SELECT。
  • UNION:在 UNION 语句中,UNION 之后出现的 SELECT。
  • DERIVED:在 FROM 中出现的子查询将被标记为 DERIVED。
  • UNION RESULT:UNION 查询的结果。

table:

表示查询用到的表名,每行都有对应的表名,表名除了正常的表之外,也可能是以下列出的值:

  • <unionM,N>: 本行引用了 id 为 M 和 N 的行的 UNION 结果;
  • <derivedN>: 本行引用了 id 为 N 的表所产生的的派生表结果。派生表有可能产生自 FROM 语句中的子查询。
  • <subqueryN>: 本行引用了 id 为 N 的表所产生的的物化子查询结果。

type:

查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

常见的几种类型具体含义如下:

  • system:如果表使用的引擎对于表行数统计是精确的(如:MyISAM),且表中只有一行记录的情况下,访问方法是 system ,是 const 的一种特例。
  • const:表中最多只有一行匹配的记录,一次查询就可以找到,常用于使用主键或唯一索引的所有字段作为查询条件。
  • eq_ref:当连表查询时,前一张表的行在当前这张表中只有一行与之对应。是除了 system 与 const 之外最好的 join 方式,常用于使用主键或唯一索引的所有字段作为连表条件。
  • ref:使用普通索引作为查询条件,查询结果可能找到多个符合条件的行。
  • index_merge:当查询条件使用了多个索引时,表示开启了 Index Merge 优化,此时执行计划中的 key 列列出了使用到的索引。
  • range:对索引列进行范围查询,执行计划中的 key 列表示哪个索引被使用了。
  • index:查询遍历了整棵索引树,与 ALL 类似,只不过扫描的是索引,而索引一般在内存中,速度更快。
  • ALL:全表扫描。

possible_keys:

possible_keys 列表示 MySQL 执行查询时可能用到的索引。如果这一列为 NULL ,则表示没有可能用到的索引;这种情况下,需要检查 WHERE 语句中所使用的的列,看是否可以通过给这些列中某个或多个添加索引的方法来提高查询性能。

key:

key 列表示 MySQL 实际使用到的索引。如果为 NULL,则表示未用到索引。

key_len:

key_len 列表示 MySQL 实际使用的索引的最大长度;当使用到联合索引时,有可能是多个列的长度和。在满足需求的前提下越短越好。如果 key 列显示 NULL ,则 key_len 列也显示 NULL 。

rows:

rows 列表示根据表统计信息及选用情况,大致估算出找到所需的记录或所需读取的行数,数值越小越好。

Extra:

这列包含了 MySQL 解析查询的额外信息,通过这些信息,可以更准确的理解 MySQL 到底是如何执行查询的。常见的值如下:

  • Using filesort:在排序时使用了外部的索引排序,没有用到表内索引进行排序。
  • Using temporary:MySQL 需要创建临时表来存储查询的结果,常见于 ORDER BY 和 GROUP BY。
  • Using index:表明查询使用了覆盖索引,不用回表,查询效率非常高。
  • Using index condition:表示查询优化器选择使用了索引条件下推这个特性。
  • Using where:表明查询使用了 WHERE 子句进行条件过滤。一般在没有使用到索引的时候会出现。
  • Using join buffer (Block Nested Loop):连表查询的方式,表示当被驱动表的没有使用索引的时候,MySQL 会先将驱动表读出来放到 join buffer 中,再遍历被驱动表与驱动表进行查询。

这里提醒下,当 Extra 列包含 Using filesort 或 Using temporary 时,MySQL 的性能可能会存在问题,需要尽可能避免。

以上就是带你学习MySQL执行计划的详细内容,更多关于MySQL执行计划的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL 全文检索的使用示例
Jun 07 MySQL
详解MySQL多版本并发控制机制(MVCC)源码
Jun 23 MySQL
mysql如何配置白名单访问
Jun 30 MySQL
MySQL索引是啥?不懂就问
Jul 21 MySQL
彻底解决MySQL使用中文乱码的方法
Jan 22 MySQL
mysql中DCL常用的用户和权限控制
Mar 31 MySQL
mysql查询结果实现多列拼接查询
Apr 03 MySQL
MySQL数据库优化之通过索引解决SQL性能问题
Apr 10 MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 MySQL
sql注入报错之注入原理实例解析
Jun 10 MySQL
Mysql中的触发器定义及语法介绍
Jun 25 MySQL
一文解答什么是MySQL的回表
Aug 05 MySQL
MySQL完整性约束的定义与实例教程
MySQL注入基础练习
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 #MySQL
MySql开发之自动同步表结构
mysql升级到5.7时,wordpress导数据报错1067的问题
May 27 #MySQL
解决Navicat for Mysql连接报错1251的问题(连接失败)
You might like
YII模块实现绑定二级域名的方法
2014/07/09 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
飞鱼(shqlsl) javascript作品集
2006/12/16 Javascript
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
2009/08/26 Javascript
JavaScript 里的类数组对象
2015/04/08 Javascript
基于JS实现的倒计时程序实例
2015/07/24 Javascript
探寻JavaScript中this指针指向
2016/04/23 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
jQuery获取及设置表单input各种类型值的方法小结
2016/05/24 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
2016/11/07 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
JavaScript实现简单生成随机颜色的方法
2017/09/21 Javascript
vue-cli启动本地服务局域网不能访问的原因分析
2018/01/22 Javascript
Javascript删除数组里的某个元素
2019/02/28 Javascript
vue 解决数组赋值无法渲染在页面的问题
2019/10/28 Javascript
js实现tab栏切换效果
2020/08/02 Javascript
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
[55:16]Mski vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
videocapture库制作python视频高速传输程序
2013/12/23 Python
Python实现采用进度条实时显示处理进度的方法
2017/12/19 Python
Python之两种模式的生产者消费者模型详解
2018/10/26 Python
Python3爬虫之自动查询天气并实现语音播报
2019/02/21 Python
详解Python可视化神器Yellowbrick使用
2019/11/11 Python
python getopt模块使用实例解析
2019/12/18 Python
python使用ctypes调用扩展模块的实例方法
2020/01/28 Python
django和flask哪个值得研究学习
2020/07/31 Python
canvas绘制圆角头像的实现方法
2019/01/17 HTML / CSS
澳大利亚汽车零部件、音响及配件超市:Automotive Superstore
2018/06/19 全球购物
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
运动会表扬稿大全
2014/01/16 职场文书
2014年财政所工作总结
2014/11/22 职场文书
锦旗赠语
2015/06/23 职场文书
2019年大学生职业生涯规划书最新范文
2019/03/25 职场文书
2019年度政务公开考核工作总结模板
2019/11/11 职场文书
MySQL之PXC集群搭建的方法步骤
2021/05/25 MySQL