带你学习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 角色(role)功能介绍
Apr 24 MySQL
MySql学习笔记之事务隔离级别详解
May 12 MySQL
详解MySQL的Seconds_Behind_Master
May 18 MySQL
详解mysql三值逻辑与NULL
May 19 MySQL
带你学习MySQL执行计划
May 31 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
MySQL外键约束(FOREIGN KEY)案例讲解
Aug 23 MySQL
SQL基础的查询语句
Nov 11 MySQL
解决MySQL添加新用户-ERROR 1045 (28000)的问题
Mar 03 MySQL
解决Mysql报错 Table 'mysql.user' doesn't exist
May 06 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
手把手带你彻底卸载MySQL数据库
Jun 14 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
php图片缩放实现方法
2014/02/20 PHP
php过滤敏感词的示例
2014/03/31 PHP
CI框架中$this-&gt;load-&gt;library()用法分析
2016/05/18 PHP
Yii全局函数用法示例
2017/01/22 PHP
js函数使用技巧之 setTimeout(function(){},0)
2009/02/09 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
Jquery AJAX POST与GET之间的区别
2013/11/14 Javascript
js判断手机和pc端选择不同执行事件的方法
2015/01/30 Javascript
javascript模拟C#格式化字符串
2015/08/26 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
jQuery插件ajaxFileUpload使用实例解析
2016/10/19 Javascript
Vue.use源码分析
2017/04/22 Javascript
js实现字符全排列算法的简单方法
2017/05/01 Javascript
vue实现图书管理demo详解
2017/10/17 Javascript
这应该是最详细的响应式系统讲解了
2019/07/22 Javascript
Vue 利用指令实现禁止反复发送请求的两种方法
2019/09/15 Javascript
layui table单元格事件修改值的方法
2019/09/24 Javascript
Vue实现图片与文字混输效果
2019/12/04 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
JavaScript享元模式原理与用法实例详解
2020/03/09 Javascript
JS array数组检测方式解析
2020/05/19 Javascript
[01:14]英雄,所敬略同——2018完美盛典宣传视频
2018/12/05 DOTA
对Python 数组的切片操作详解
2018/07/02 Python
python按比例随机切分数据的实现
2019/07/11 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
Pandas+Matplotlib 箱式图异常值分析示例
2019/12/09 Python
python3.x中安装web.py步骤方法
2020/06/23 Python
Python制作数据预测集成工具(值得收藏)
2020/08/21 Python
美国最大的半成品净菜电商:Blue Apron(蓝围裙)
2018/04/27 全球购物
单方离婚协议书范本2014
2014/10/28 职场文书
机修车间主任岗位职责
2015/04/08 职场文书
离婚被告答辩状
2015/05/22 职场文书
转变工作作风心得体会
2016/01/23 职场文书
离婚协议书格式范本
2016/03/18 职场文书
2016最新离婚协议书范本及程序
2016/03/18 职场文书
基于python制作简易版学生信息管理系统
2021/04/20 Python