文档章节

在MySQL中使用explain查询SQL的执行计划

若离x
 若离x
发布于 2018/05/05 18:16
字数 1790
阅读 2542
收藏 136

1、什么是MySQL执行计划

       要对执行计划有个比较好的理解,需要先对MySQL的基础结构及查询基本原理有简单的了解。

        MySQL本身的功能架构分为三个部分,分别是 应用层、逻辑层、物理层,不只是MySQL ,其他大多数数据库产品都是按这种架构来进行划分的。

  • 应用层,主要负责与客户端进行交互,建立链接,记住链接状态,返回数据,响应请求,这一层是和客户端打交道的。
  • 逻辑层,主要负责查询处理、事务管理等其他数据库功能处理,以查询为例。

        首先接收到查询SQL之后,数据库会立即分配一个线程对其进行处理,第一步查询处理器会对SQL查询进行优化,优化后会生成执行计划,然后交由计划执行器来执行。

        计划执行器需要访问更底层的事务管理器,存储管理器来操作数据,他们各自的分工各有不同,最终通过调用物理层的文件获取到查询结构信息,将最终结果响应给应用层。

  • 物理层,实际物理磁盘上存储的文件,主要有分文数据文件,日志文件。

   通过上面的描述,生成执行计划是执行一条SQL必不可少的步骤,一条SQL性能的好坏,可以通过查看执行计划很直观的看出来,执行计划提供了各种查询类型与级别,方面我们进行查看以及为作为性能分析的依据。

 

2、如何分析执行计划

     MySQL为我们提供了 explain 关键字来直观的查看一条SQL的执行计划。

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

      下面我们使用 explain 做一个查询,如下:

mysql> explain select * from payment;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
|  1 | SIMPLE      | payment | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 16086 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
1 row in set, 1 warning (0.01 sec)

     查询结构中有12列,理解每一列的含义,对理解执行计划至关重要,下面用一个表格的形式进行说明。

列名 说明
id SELECT识别符,这是SELECT的查询序列号。
select_type

SELECT类型,可以为以下任何一种:

  • SIMPLE:简单SELECT(不使用UNION或子查询)
  • PRIMARY:最外面的SELECT
  • UNION:UNION中的第二个或后面的SELECT语句
  • DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
  • UNION RESULT:UNION 的结果
  • SUBQUERY:子查询中的第一个SELECT
  • DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
  • DERIVED:导出表的SELECT(FROM子句的子查询)
table 输出的行所引用的表
partitions 如果查询是基于分区表的话,显示查询将访问的分区。
type

联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:

  • system:表仅有一行(=系统表)。这是const联接类型的一个特例。
  • const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
  • eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。
  • ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
  • ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。
  • index_merge:该联接类型表示使用了索引合并优化方法。
  • unique_subquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
  • index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range:只检索给定范围的行,使用一个索引来选择行。
  • index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
  • ALL:对于每个来自于先前的表的行组合,进行完整的表扫描,说明查询就需要优化了

一般来说,得保证查询至少达到range级别,最好能达到ref。

possible_keys 指出MySQL能使用哪个索引在该表中找到行
key 显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
key_len 显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好
ref 显示使用哪个列或常数与key一起从表中选择行。
rows 显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。
filtered 显示了通过条件过滤出的行数的百分比估计值。
Extra

该列包含MySQL解决查询的详细信息

  • Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
  • Select tables optimized away MySQL根本没有遍历表或索引就返回数据了,表示已经优化到不能再优化了
  • Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
  • range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
  • Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,说明查询就需要优化了
  • Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
  • Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果,说明查询就需要优化了
  • Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
  • Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
  • Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

    根据上述表格,可以在执行计划分析上提供很好的帮助。

 

© 著作权归作者所有

若离x
粉丝 45
博文 75
码字总数 83739
作品 0
广州
私信 提问
加载中

评论(2)

mark35
mark35
mysql的explain聊胜于无
JasonDavic
JasonDavic
很详细
十、MySQL的SQL优化之定位SQL的问题 - 系统的撸一遍MySQL

找出SQL慢的原因 谈到MySQL不得不说的就是大家都会遇到的性能问题,今天就记录一下SQL优化相关的技巧。 检查MySQL状态 通过检查SQL语句的状态有助于MySQL的优化,首先介绍 show status命令 ...

logbird
2016/11/04
495
0
如何高效快速地优化MySQL、SQL语句(附源码)

作者介绍 韩锋,宜信技术研发中心数据库架构师。精通多种关系型数据库,曾任职于当当网、TOM在线等公司,曾任多家公司首席DBA、数据库架构师等职,多年一线数据库架构、设计、开发经验。著有...

Yomut
2016/10/10
208
1
结合explain extended浅析使用mysql in 的效率

用explain extended查看执行计划会比explain多一列 filtered。 filtered列给出了一个百分比的值,这个百分比值和rows列的值一起使用,可以估计出那些将要和explain中的前一个表进行连接的行的...

小小人故事
2015/12/05
218
0
如何用一款小工具大大加速MySQL SQL语句优化(附源码)

作者介绍 韩锋,宜信技术研发中心数据库架构师。精通多种关系型数据库,曾任职于当当网、TOM在线等公司,曾任多家公司首席DBA、数据库架构师等职,多年一线数据库架构、设计、开发经验。著有...

韩锋
2016/09/26
0
0
浅谈mysql执行计划之type

mysql执行计划作为分析一条sql的执行效率的工具十分有效,通过explain关键字便可查看select语句的具体执行计划,分析其是否按我们设计的执行,是否使用了索引,是否全表扫描等等。不过有很多...

SawyerZhou
2017/12/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一起来学Java8(五)——接口默认方法

Java8新加入一个特性,允许在接口方法中给定一个默认实现。前提是在方法前面加一个default关键字。 public interface InterfaceMethod {default void say() {System.out.println("hello...

猿敲月下码
18分钟前
8
0
weed3-2.3.3.查询之缓存控制

Weed3 一个超轻量级ORM框架(只有0.1Mb哦) 源码:https://github.com/noear/weed3 源码:https://gitee.com/noear/weed3 缓存控制,是查询中的重点 框架提供的是控制服务。而非缓存服务本身...

刘之西东
21分钟前
9
0
Java Web 中对 ServletRequest 的一些非常规操作解决方案

1. 前言 ServletRequest 是我们搞 Java Web 经常接触的 Servlet Api 。有些时候我们要经常对其进行一些操作。这里列举一些经常的难点操作。 2. 提取 body 中的数据 前后端交互我们会在 body...

码农小胖哥
今天
33
0
《Dual Encoding U-Net for Retinal Vessel Segmentation》阅读笔记-MICCAI2019

作者:Bo Wang1,2, Shuang Qiu2, and Huiguang He1,2,3 目的:Retinal Vessel Segmentation is an essential step for the early diagnosis of eye-related diseases, such as diabetes and ......

JungleKing
今天
33
0
一次看懂 Https 证书认证

TLS > 传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为网际网路通信,提供安全及数据完整性保障。 如图,TLS...

极客收藏夹
今天
36
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部