当前位置: 首页 > news >正文

1201_mysql查询语句select执行流程

查询语句select执行流程,如下图所示,其核心流程可概括为:

flowchart TD A["客户端提交 SELECT 语句"] --> B["连接器<br>管理连接, 权限验证"] B --> C["查询缓存<br>(MySQL 8.0+已移除)<br>命中则直接返回"] C --> D["解析器<br>语法分析, 生成解析树"] D --> E["预处理器<br>语义检查, 对象/权限验证"] E --> F["优化器<br>生成最优执行计划"] F --> G["执行器<br>调用存储引擎接口执行计划"] G --> H["存储引擎<br>(InnoDB)<br>执行索引查找/数据读取"] H --> I["返回结果集至客户端"]

核心组件阶段

1. 连接器 (Connector)

  • 职责:管理客户端连接、身份认证和权限校验。
  • 流程:客户端发起连接,连接器验证用户名、密码和主机权限。验证通过后,会建立连接并管理该连接的所有状态。如果该用户权限有变更,已在线的连接不会受影响,需重新建立连接才能生效。

2. 查询缓存 (Query Cache) - (MySQL 8.0+已移除)

  • 职责:缓存完整的查询结果(Key-Value形式,Key是查询SQL,Value是结果集)。
  • 流程:如果命中缓存,结果直接返回给客户端。但由于任何表的数据更新都会导致该表的所有缓存失效,在频繁写的场景下缓存命中率极低,且管理和检查缓存带来额外开销,因此该功能在 MySQL 8.0 中被彻底移除。

3. 解析器 (Parser)

  • 职责:进行词法分析语法分析
  • 流程
    • 词法分析:将完整的SQL语句拆分成一个个的“词元”(Token),例如识别 SELECTFROM表名列名 等。
    • 语法分析:根据MySQL的语法规则,检查这些词元组合成的SQL语句是否符合规范。如果语法错误(如缺少关键字),会在此阶段抛出错误。解析通过后,会生成一棵解析树(Abstract Syntax Tree)。

4. 预处理器 (Preprocessor) / 解析器后续阶段

  • 职责:进行语义检查
  • 流程:基于解析树进行进一步验证:
    • 检查表和列名是否存在。
    • 检查 WHERE 子句中的字段是否合法。
    • * 进行展开为所有具体列名。
    • 检查用户对相关对象的访问权限
    • 进行一些简单的逻辑优化(如常量折叠)。

5. 优化器 (Optimizer)

  • 职责:将解析树转换为最优的执行计划。这是最复杂也是最关键的环节。
  • 决策内容
    • 选择访问路径:应该使用哪个索引?还是全表扫描?例如,WHERE id = 5,如果 id 有索引,优化器会决定是使用主键索引还是二级索引。
    • 选择连接顺序和算法:对于多表连接(JOIN),决定先读哪张表,以及使用哪种连接算法(Nested-Loop Join, Hash Join, etc.)。
    • 子查询优化:尝试将子查询转换为更高效的 JOIN 操作。
    • 条件简化:对 WHEREHAVING 子句中的条件进行简化。
    • 优化器基于成本模型(Cost Model)进行决策,它会估算各种执行方式的 I/O、CPU、内存等开销,选择“成本”最低的那个计划。

6. 执行器 (Executor)

  • 职责:根据优化器生成的执行计划,调用存储引擎提供的接口来执行查询。
  • 流程
    1. 在执行前,先检查用户对表是否有执行权限(如果启用了查询缓存,权限检查可能在缓存前进行)。
    2. 根据计划的指示,循环调用存储引擎接口:
      • 从第一行开始,调用存储引擎的“读下一行”接口。
      • 存储引擎通过索引或扫描找到数据并返回给执行器。
      • 执行器根据 WHERE 子句条件进行过滤。
      • 将符合条件的数据行放入结果集中。
    3. 执行器完成后,将结果集返回给客户端。

7. 存储引擎 (Storage Engine) - 以 InnoDB 为例

  • 职责真正负责数据的存储和提取。执行器发出的指令最终由存储引擎执行。
  • 流程(以索引查找为例)
    1. 定位根节点:从索引的根页(Root Page)开始。
    2. 遍历非叶子节点:在 B+Tree 的非叶子节点层进行二分查找,确定目标数据所在的下层页(指针)。
    3. 定位叶子节点:不断向下遍历,直到找到包含目标数据的叶子节点页。
    4. 在叶子节点中查找
      • 等值查询:在叶子节点内使用二分查找定位到精确的记录。
      • 范围查询:找到范围的起始点,然后沿着叶子节点间的双向链表向后(或向前)扫描,直到范围结束。
    5. 返回记录:将找到的记录返回给执行器(如果是“覆盖索引”,则直接从索引中返回数据,否则需要根据主键ID回表查询主索引获取完整数据行)。
http://www.hskmm.com/?act=detail&tid=9772

相关文章:

  • 记录---vue3项目实战 打印、导出PDF
  • 09
  • node.js安装(绿色版)
  • 08
  • selenium完整版一览 - 教程
  • 创龙 瑞芯微 RK3588 国产2.4GHz八核 工业开发板—开发环境搭建(二) - 创龙科技
  • ctfshow web55
  • ctfshow web58
  • ctfshow web57
  • 01
  • test 1
  • 关于如何计算空间
  • ECT-OS-JiuHuaShan框架实现的元推理,是新质生产力的绝对标杆
  • 线性调频信号(LFM)在雷达中的时域及频域MATLAB编程
  • Ubuntu 18.04 LTS 安装 6.10.10 内核 - 教程
  • 国标GB28181视频平台EasyGBS核心功能解密:如何实现海量设备的录像精准检索与高效回放?
  • 最大流判定+拆点
  • C++ 左值、右值、左值引用、右值引用
  • 基数排序模板(Radix Sort)
  • [项目开发经验分享]基于强类型事件的类型参数传递问题 —— 在 .NET Winform项目中如何设计泛型事件总线以实现UI与核心层的解耦
  • python3安装pip3
  • 堆基础知识
  • RUST 实现 Future trait
  • 行程长度编码
  • mysql 虚拟列,可以简化 SQL 逻辑、提升查询效率
  • Flash Attention算法动画
  • PointNetwork-求解TSP-05 - jack
  • 多站点的TSP问题求解-06 - jack
  • Windows 11如何进入安全模式
  • C# CAN通信上位机系统设计与实现