Skip to content

执行一条 select 语句,期间发生了什么?

MySQL 执行流程

MySQL 的架构分为两层:Server 层和存储引擎层

  • **Server 层负责建立连接、分析和执行 SQL。**MySQL 大多数的核心功能模块都在这实现,主要包括连接器,查询缓存、解析器、预处理器、优化器、执行器等。另外,所有的内置函数(如日期、时间、数学和加密函数等)和所有跨存储引擎的功能(如存储过程、触发器、视图等。)都在 Server 层实现。

  • **存储引擎层负责数据的存储和提取。**支持 InnoDB、MyISAM、Memory 等多个存储引擎,不同的存储引擎共用一个 Server 层。现在最常用的存储引擎是 InnoDB,从 MySQL 5.5 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。我们常说的索引数据结构,就是由存储引擎层实现的,不同的存储引擎支持的索引类型也不相同,比如 InnoDB 支持索引类型是 B+树 ,且是默认使用,也就是说在数据表中创建的主键索引和二级索引默认使用的是 B+ 树索引。

第一步:连接器

  • 与客户端进行 TCP 三次握手建立连接;

  • 校验客户端的用户名和密码,如果用户名或密码不对,则会报错;

  • 如果用户名和密码都对了,会读取该用户的权限,然后后面的权限逻辑判断都基于此时读取到的权限;

第二步:查询缓存

连接器得工作完成后,客户端就可以向 MySQL 服务发送 SQL 语句了,MySQL 服务收到 SQL 语句后,就会解析出 SQL 语句的第一个字段,看看是什么类型的语句。

如果 SQL 是查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句,value 为 SQL 语句查询的结果。

查询缓存的鸡肋之处

对于更新比较频繁的表,查询缓存的命中率很低的,因为只要一个表有更新操作,那么这个表的查询缓存就会被清空。如果刚缓存了一个查询结果很大的数据,还没被使用的时候,刚好这个表有更新操作,查询缓冲就被清空了,相当于缓存了个寂寞。

所以,MySQL 8.0 版本直接将查询缓存删掉了,也就是说 MySQL 8.0 开始,执行一条 SQL 查询语句,不会再走到查询缓存这个阶段了。

第三步:解析 SQL

在正式执行 SQL 查询语句之前, MySQL 会先对 SQL 语句做解析,这个工作交由「解析器」来完成。

解析器会做如下两件事情:

  • 词法分析MySQL会根据你输入的字符串识别出关键字出来,例如,SQL语句select username from userinfo,在分析之后,会得到 4 个 Token,其中有 2 个 Keyword,分别为 select 和 from:

  • 语法分析:根据词法分析的结果,语法解析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法,如果没问题就会构建出 SQL 语法树,这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。

第四步:执行 SQL

每条SELECT查询语句流程主要可以分为下面这三个阶段:

  • prepare阶段,也就是预处理阶段;

  • optimize 阶段,也就是优化阶段;

  • execute阶段,也就是执行阶段;

预处理阶段

  • 检查 SQL 查询语句中的表或者字段是否存在;
  • select *中的*符号,扩展为表上的所有列;

表或字段是否存在的判断,不是在解析器里做的,而是在 prepare 阶段。

优化器阶段

经过预处理阶段后,还需要为 SQL 查询语句先制定一个执行计划,这个工作交由「优化器」来完成的。

优化器主要负责将 SQL 查询语句的执行方案确定下来,比如在表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引。

执行器阶段

经历完优化器后,就确定了执行方案,接下来 MySQL 就真正开始执行语句了,这个工作是由「执行器」完成的。在执行的过程中,执行器就会和存储引擎交互了,交互是以记录为单位的。

接下来,用三种方式执行过程:

  • 主键索引查询

    主键索引查询是通过主键索引来快速定位数据的一种查询方式。主键索引是唯一的,并且通常是聚簇索引(Clustered Index),这意味着数据在物理上按照主键顺序存储。

  • 全表扫描

    全表扫描是逐行读取表中的所有数据,并应用过滤条件的一种查询方式。全表扫描通常在没有合适的索引时使用。

  • 索引下推

    索引下推(Index Condition Pushdown, ICP)是一种优化技术,用于在索引扫描过程中提前应用过滤条件,从而减少回表操作的次数,提高查询性能。

最后更新于:

如有转载或 CV 的请标注本站原文地址