当前位置: 首页 > MySQL数据库

MySQL查询语句执行流程是什么

时间:2026-01-26 14:21:16

架构图

解析器

解析器的作用是对客户端传来的 SQL 语句进行以下工作:

    语法解析:检查 SQL 语句的语法,括号、引号是否闭合等

    词法解析:把 SQL 语句中的关键词、表名、字段名拆分成一个个节点,最终得到一颗解析树

    预处理器

    解析器主要是检查语法词法方面,但是如果语法词法都正确,但是表、字段是不存在的,那么这段 SQL 语句也是无法正确执行的。

    所以预处理器的作用是:语义解析,判断解析树的语义是否正确,表、字段这些是否存在,预处理后会得到一颗新的解析树。

    查询优化器

    查询优化器结构

    在 MySQL 中一条 SQL 语句的执行方式有多种,虽然最终都会得到相同的结果,但是存在开销上的差异,具体选择哪一种执行方式是由查询优化器来决定的。比如说:

      表中有多个索引可以选择,具体选择哪一个索引

      当我们对多张表进行关联查询时,以哪一张表的数据为基准表

      查询优化器是基于开销(cost)的优化器,它的工作原理是根据解析树生成的多种执行计划,会评估各种执行方式所需的开销(cost),最终会得到一个开销最小的执行计划作为最终方案。

      但是这个开销最小的执行方式不一定是最优的执行方式,比如本该使用索引,却进行了全表扫描等。虽然查询优化器中有《优化》两个字,但是这个优化并不是万能的,很多时候更加需要考虑 SQL 语句书写得是否合理。

      逻辑查询优化

      逻辑查询优化主要负责进行一些关系代数对 SQL 语句进行优化,从而使 SQL 语句执行效率更高

      逻辑查询优化我们可以使用几个案例来简单理解

        子查询合并

        合并前

        SELECT * FROM t1 WHERE a1<10 AND (
        EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND t2.b2=1) OR
        EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND t2.b2=2)
        );

        合并后

        SELECT * FROM t1 WHERE a1<10 AND (
        EXISTS(SELECT a2 FROM t2 WHERE t2.a2<5 AND (t2.b2=1 OR t2.b2=2)
        );

        把多个子查询通过合并查询条件而合并查询,把多次连接操作减少为单次表扫描和单次连接

        等价谓词重写

        像我们熟悉的 like 模糊查询,% 写在条件后面才会进行索引范围查询,其实这是查询优化器的功劳

        假设使用的条件都是有建立索引的,重写前

        SELECT * FROM USERINFO WHERE name LIKE 'Abc%';

        重写后

        SELECT * FROM USERINFO WHERE name >= 'Abc' AND name < 'Abd';

        这就是为什么能进行索引范围查询的答案

        条件简化

        条件简化也是利用一些等式、代数关系来实现简化

          去除表达式中的冗余括号,减少语法分析时产生的AND和OR 树的层 次,比如 ((a AND b) AND (c AND d)) 简化为 a AND b AND c AND d

          常量传递,比如 col1 = col2 AND col2 = 3 简化为 col1 = 3 AND col2 = 3

          表达式计算,对于一些可直接求解的表达式会转换为最终的计算结果,比如 col1 = 1+2 简化为 col1 = 3

          物理查询优化

          物理查询优化主要做的工作是根据 SQL 语句分别对多种执行计划进行开销的评估

          物理查询优化主要解决以下几个问题:

            单表扫描中采用哪种方式是开销最小的(扫描索引+回表 or 全表扫描)

            存在表连接的时候使用哪种连接方式是开销最小的

            简单了解一下代价评估,代价评估是基于 CPU 代价和 IO 代价两个维度的

            扫描方式代价评估公式
            顺序扫描N_page * a_page_IO_time + N_tuple * a_tuple_CPU_time
            索引扫描C_index + N_page_index * a_page_IO_time

            上述参数说明如下:

              a_page_IO_time, 一个数据页加载的IO耗时

              N_page,数据页数量

              N_tuple,元组数(元组理解为一行数据)

              a_tuple_CPU_time,一个元组从数据页中解析的CPU耗时

              C_index,索引的IO耗时

              N_page_index,索引页数量

              关于索引成本计算可以参考这篇文章:MySQL查询为什么选择使用这个索引?——基于MySQL 8.0.22索引成本计算

              执行计划

              执行计划是查询优化器的产物,最终会交给存储引擎进行执行。执行计划可以帮助我们得知 MySQL 会怎么执行这条 SQL 语句。

              使用 explain 关键字查看 SQL 语句的执行计划,可以得到以下信息:

                id:嵌套查询中查询的执行顺序

                possible_keys:本次查询可能用到的索引

                Key:实际用到的索引

                rows:得到结果大概要检索多少行数据

                select_type多表之间的连接类型

                extra:额外的信息,是否有索引覆盖、索引下推等

                存储引擎

                MySQL 服务端规定了数据如何存储、如何提取、如何更新的规范,这个规范由存储引擎来实现,不同的存储引擎的实现方式不同,所以不同的存储引擎会呈现其独特的功能和特点。其中最常用的存储引擎是 InnoDB 和 MyISAM

                简单说说这两款存储引擎的特点

                InnoDB:

                  支持外键、事务,保证了数据的完整性和一致性

                  支持更细的锁粒度,对锁的控制更好,读写效率更高

                  MyISAM

  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素