MySQL 查询语句是怎么执行的?(总结篇)

经过一周的持续整理与总结,终于完成了一条简单查询语句执行过程各个阶段分析的文章。写文章的过程,既是分享输出,也是重新学习的过程。

在这个过程中,也有不小的收获,自己知道和写出来让大家都知道,这个知识转换输出的过程,并不是件容易的事,需要对知识点有更深刻的理解。研究源码时以为自己已经理解的一些知识点,在写文章的过程中,发现并不能清楚的写出来,这时候又继续回头去研究源码,对于这类知识点又有了更深刻的理解。

也感谢同事、朋友们帮忙转发,传播文章,第一次体验到自己写的东西有人在看,这种感觉也是不错的,虽然现在看的人还少,我也会持续输出,一方面是提升自己,另一方面也希望给有需要的小伙伴带来一些帮助。

由于查询语句执行过程涉及的环节比较多,整个执行过程拆分为 6 篇进行介绍,为了小伙伴们对执行过程有个整体的了解,有必要对每篇文章中的内容做一个概括性总结。

1. 词法分析 & 语法分析 <- 点击阅读

第 1 篇,先介绍了 MySQL 的词法分析器是自己实现的,并没有使用开源工具,猜测主要是因为开源的词法分析器要兼顾通用性,不如自己实现执行效率高。

然后介绍了 MySQL 语法分析器使用了开源工具 Bison,因为语法分析器相比于词法分析器来说,没有那么多复杂的逻辑,主要都是针对语法的处理,所以用开源工具实现不涉及到执行效率问题,践行了不重复发明轮子的理念。

最后介绍了在词法分析 & 语法分析过程中,会初始化 select 子句中的字段为 Item_field 类实例,初始化 from 子句中的表为 TABLE_LIST 类实例,初始化 where 条件中的字段为 Item_field 类实例。

2. 查询准备阶段 <- 点击阅读

第 2 篇,先介绍了打开表的过程,涉及到表缓存(TABLE 类实例缓存)、表定义缓存(TABLE_SHARE 类实例缓存)、读取 frm 文件。

然后介绍了把 select 子句中的星号(*)替换为表字段的过程。

最后介绍了 where 条件中的 Item_field 类实例找到其对应字段 Field 类实例的过程,并设置字段内容和 where 条件中的值进行比较时执行的函数。找到 Item_field 类对应字段 Field 类实例的过程中,使用了两级缓存,以及兜底逻辑:循环遍历表中字段。

3. 从 InnoDB 读数据 <- 点击阅读

第 3 篇,以 InnoDB 为例讲述从存储引擎中读取数据的过程,先介绍了创建 InnoDB 存储引擎实例,在这个过程中会建立 MySQL 和 InnoDB 索引的映射关系,以及会创建用于 InnoDB 执行查询过程的查询模板。

然后是填充查询模板的过程,主要介绍了文中示例 SQL 执行时涉及到的三个方面,分别是:根据查询优化阶段确定的要使用的索引,找到 InnoDB 中索引的实例;对回表的概念进行了说明;以及 InnoDB 会返回哪些字段内容给 server 层,又是怎么返回内容的?

最后是 InnoDB 执行查询的过程,先介绍了什么是预读缓存,以及什么情况下会使用预读缓存;简单介绍了 InnoDB 都是从 Buffer Pool 中读取数据;InnoDB 怎么通过一致性视图判断记录是否可见。

4. WHERE 条件 <- 点击阅读

第 4 篇,先介绍了 where 条件在源码中实现为类似树状的结构,并用一张图呈现了示例 SQL 中 where 条件的结构。

然后介绍了从存储引擎读取到的记录和 where 条件中的值进行比较的过程。

最后介绍了三种特殊类型的字段(set、enum、bit)作为 where 条件时,是怎么和记录中的字段内容进行比较的。

5. 发送数据给客户端 <- 点击阅读

第 5 篇,先介绍了 MySQL 会发送字段的哪些元数据信息给客户端,然后介绍各种类型字段,在发送给客户端之前,是怎么转换为字符串格式的,以及还会做哪些逻辑处理。

6. 网络缓冲区 <- 点击阅读

第 6 篇,从客户端和服务端数据交互的基本单元数据包(Packet)开始,介绍了 MySQL 中的连接缓冲区、结果集缓冲区,它们的自动增长逻辑和上下限;超过 16M 的大数据怎么发送和接收;net_buffer_length、max_allowed_packet 两个系统变量的配置,以及一个不起眼的小东西 Block Size。


这次的查询语句执行过程分析,以一条简单查询语句为基础,也是我写执行过程分析系统文章的基础篇,接下来计划要写的方向有这些:

  • 文件排序
  • group by 使用索引的执行过程
  • group by 使用临时表的执行过程
  • 内存临时表 & 磁盘临时表
  • 聚合函数的实现
  • 查询优化器
  • 子查询优化
    • 表上拉(Table Pullout)
    • 重复值消除(Duplicate Weedout)
    • 首次匹配(First Match)
    • 松散扫描(Loose Scan)
    • 子查询物化 Join
  • 连接(Join)查询



欢迎扫码关注公众号,我们一起学习更多 MySQL 知识: