高性能 MySQL(十):执行一个查询的过程

高性能 MySQL(十):执行一个查询的过程_第1张图片

❤️ 个人主页:水滴技术
订阅专栏:高性能 MySQL
支持水滴:点赞 + 收藏⭐ + 留言

系列文章目录

高性能 MySQL(一):逻辑架构

高性能 MySQL(二):并发控制(锁)

高性能 MySQL(三):事务与锁详解

高性能 MySQL(四):多版本并发控制(MVCC)

高性能 MySQL(五):设计表结构时,如何选择数据类型会更高效?

高性能 MySQL(六):索引类型

高性能 MySQL(七):11个高性能的索引策略

高性能 MySQL(八):通过优化数据访问,来解决慢查询

高性能 MySQL(九):通过重构查询语句,来解决慢查询


大家好,我是水滴~~

当希望 MySQL 能够以更高的性能运行查询时,最好的办法就是搞清楚 MySQL 是如何优化和执行查询的。一旦理解这一点,很多查询优化工作实际上就是遵循一些原则,让优化器按照预想的方式运行。

下图为 MySQL 执行一个查询的过程,我们一起看看它们的第一步都做的什么吧。

高性能 MySQL(十):执行一个查询的过程_第2张图片


文章目录

    • 系列文章目录
    • 一、客户端/服务器通信协议
    • 二、查询缓存
    • 三、查询优化处理
      • 1. 语法解析器和预处理
      • 2. 查询优化器
      • 3. 执行计划
    • 四、查询执行引擎
    • 五、返回结果给客户端


一、客户端/服务器通信协议

一般来说,我们不需要理解 MySQL 通信协议的内部细节,只需要大致理解通信协议是如何工作的。MySQL 客户端与服务端之间的通信协议是“半双工”的,这意味着,在任何一个时刻,要么是由服务器向客户端发送数据,要么是由客户端向服务器发送数据,这两个动作不能同时发生。

需要注意的一点是,当客户端从服务器取数据时,看起来是一个拉数据的过程,但实际上是 MySQL 服务器在向客户端推送数据的过程。

查询状态:对于一个 MySQL 连接,或者说一个线程,任何时刻只会有一个状态,该状态表示了 MySQL 当前正在做什么(可以通过show full processlist命令查看当前的状态)。

在一个查询的生命周期中,状态会变化很多次。下面是查询状态的列表:

  • Sleep:线程正在等待客户端发送新的请求。
  • Query:线程正在执行查询或者正在将结果发送给客户端。
  • Locked:在 MySQL 服务器端,该线程正在等待表锁。
  • Analyzing and statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划。
  • Copying to tmp table [on disk]:线程正在执行查询,并且将结果集都复制到一个临时表中(例如:执行 group by、文件排序或union操作)。如果这个状态后面还有“on disk”标记,那表示 MySQL 正在将一个内存中的临时表拷贝到磁盘上。
  • Sorting result:线程正在对结果集进行排序。
  • Sending data:这表示多种情况,线程可能在多个状态之间传送数据,或者在生成结果集,或者在向客户端返回数据。

了解这些状态的基本含义非常有用,这可以让你很快地了解当前查询执行的状态。若某个地方有了异常,也能很快地诊断出问题来。

二、查询缓存

在解析一个查询语句之前,如果查询缓存是打开的,那么 MySQL 会优先检查这个查询是否命中查询缓存中的数据。这个检查是通过一个对大小写敏感的哈希表实现的,如果没有匹配出缓存结果,那么查询会进入下一阶段的处理。

如果当前查询恰好命中了查询缓存,那么 MySQL 会直接从缓存中拿到结果并返回给客户端(在返回结果之前,MySQL 会检查一次用户权限,权限没问题会直接返回)。

三、查询优化处理

查询的生命周期的下一步,是将一个 SQL 转换成一个执行计划,这个过程称之为查询优化处理。这包括了多个子阶段:解析 SQL、预处理、优化 SQL 执行计划。

1. 语法解析器和预处理

首先,MySQL 通过关键字将 SQL 语句进行解析,并生成一棵对应的“解析树”。MySQL 解析器将使用请求规则验证和解析查询。

预处理则根据一些 MySQL 规则进一步检查解析树是否合法。例如,检查数据表和数据列是否存在、名称和别名是否有歧义等。下一步,预处理器还会验证权限。

2. 查询优化器

如果语法树是合法的,那么优化器会将其转化成执行计划。一条查询可以有很多种执行方式,它们的返回结果是相同的。优化器的作用就是找到这其中最好的执行计划。

3. 执行计划

和很多其他关系数据库不同,MySQL 并不会生成查询字节码来执行查询。MySQL 生成查询的一棵指令树,然后通过存储引擎执行完成这棵指令树并返回结果。最终的执行计划包含了重构查询的全部信息。

四、查询执行引擎

执行计划生成后,MySQL 的查询执行引擎则根据这个执行计划来完成整个查询。

相对于查询优化阶段,查询执行阶段不是那么复杂:MySQL 只是简单地根据执行计划给出的指令逐步执行。在该过程中,有大量的操作需要通过调用存储引擎实现的接口来完成,这些接口称为“handler API”。

为了执行查询,MySQL 只需要重复执行计划中的各个操作,直到完成所有的数据查询。

五、返回结果给客户端

查询执行的最后一个阶段是将结果返回给客户端。即使查询不需要返回结果集给客户端,MySQL 仍然会返回这个查询的一些信息,如该查询影响的行数。

如果查询可以被缓存,那么 MySQL 在这个阶段也会将结果存放到查询缓存中。

MySQL 将结果集返回给客户端是一个增量、逐步返回的过程。结果集中的每一行都会以一个满足 MySQL 客户端/服务器通信协议的封包发送,再通过 TCP 协议进行传输,在 TCP 传输过程中,可能对 MySQL 的封包进行缓存,然后指传输。

高性能 MySQL(十):执行一个查询的过程_第3张图片

你可能感兴趣的:(《高性能,MySQL》读书笔记,mysql)