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

从零起步学习MySQL || 第五章:select语句的执行过程是怎么样的?(结合源码深度解析)

🧩 一、整体流程概览

MySQL 的执行过程可以分为两大部分:

  1. Server 层(SQL 层):负责连接管理、解析、优化、执行等逻辑。

  2. 存储引擎层(Engine 层):负责数据的存取,比如 InnoDB、MyISAM 等。

可以理解为:

Server 层决定 “查什么、怎么查”,
存储引擎层负责 “去磁盘拿数据回来”。


⚙️ 二、执行流程的 7 个核心阶段

假设你执行了:

SELECT name FROM user WHERE id = 1;

我们来看看 MySQL 内部经历的全过程。


① 连接器(Connection Manager)

  • 当客户端(比如 Navicat、Java 应用中的 JDBC)发起连接时,MySQL 首先由 连接器 处理。

  • 验证用户名、密码,建立 TCP 连接。

  • 如果连接成功,会分配一个线程来处理这个客户端的后续请求。

🧠 知识点

  • 长连接(connection pool)可以复用连接,避免频繁建立/销毁 TCP。

  • 但长连接可能导致 内存膨胀(因为线程上下文缓存),可通过 mysql_reset_connection() 重置。这一过程无需重连和重新做权限验证,但是会将连接恢复至刚刚创建完的状态。


② 查询缓存(Query Cache)【MySQL 8.0 已移除】

  • 旧版本 MySQL(<8.0)会先看这条 SQL 是否在缓存中。

  • 如果命中缓存,直接返回结果。

  • 因为更新任意表会导致缓存失效,所以性能反而不稳定,现代 MySQL 不再使用


③ 解析器(Parser)

  • 词法分析:把 SQL 拆成 token(如 SELECTnameFROMuser 等)(分析关键字)。

  • 语法分析:生成 语法树(Parse Tree)

    • 检查语法是否正确(例如是否缺少关键字等)。

    • 如果语法有问题,这里就会报错

🧠 类比理解
就像编译器在编译源代码时,先把源码拆解成语法结构。


④ 预处理器(Preprocessor)

  • 进一步验证 SQL 的合法性:

    • 表、字段是否存在;

    • 用户是否有权限;

    • 名称是否有歧义。

    • 将 * 修改为所有列

根据源码发现,如果有表或字段不存在,会在语法分析后,预处理前出现报错


⑤ 优化器(Optimizer)

这是 MySQL 智能的地方 —— 选择最优执行计划

优化器的主要任务:

  • 确定使用哪个索引;

  • 确定表连接顺序;

  • 是否可以利用索引覆盖;

  • 是否可以进行查询重写、常量折叠等。

📘 示例

SELECT * FROM user WHERE age > 20 AND name = 'Tom';

优化器可能决定:

  • 使用 name 索引(因为选择性更高),

  • 先过滤出 name='Tom' 再判断 age > 20

🧠 查看优化器决策

EXPLAIN SELECT * FROM user WHERE age > 20 AND name = 'Tom';

可查看执行计划、索引使用情况、行扫描数等。


⑥ 执行器(Executor)

索引下推

前提假设

假设 t_user 表有以下结构:

  • 主键:id(聚簇索引,存储完整行数据)。
  • 二级索引:idx_age(包含 age 列,且包含 reward 列,即索引中存储了 age 和 reward 的值)。
  • 数据示例(简化):
idagereward
12150000
222100000
32380000
424100000
525120000

有索引下推时,reward = 100000 的判断会提前到存储引擎层,减少不必要的回表。过程如下:

步骤 1:Server 层发起查询,定位初始记录

Server 层调用存储引擎接口,要求找到满足 age > 20 的第一条二级索引记录(即 age=21 对应的索引项,对应 id=1)。

步骤 2:存储引擎层提前过滤 reward 条件

存储引擎定位到 age=21 的二级索引记录后,不立即回表,而是先检查索引中包含的 reward 列:

  • 该记录的 reward=50000,不满足 reward=100000 → 直接跳过这条索引记录,不回表。
步骤 3:遍历下一条索引记录,重复过滤

存储引擎继续取下一条 age > 20 的索引记录(age=22,对应 id=2):

  • 检查索引中的 reward=100000 → 满足条件 → 执行回表:根据 id=2 到聚簇索引中取出完整行数据(id=2, age=22, reward=100000),返回给 Server 层。
步骤 4:Server 层最终校验并返回

Server 层拿到回表后的完整行,检查所有查询条件(这里只剩最终校验,通常已符合),将记录发送给客户端。

步骤 5:继续遍历剩余索引记录

存储引擎继续遍历后续 age > 20 的索引记录:

  • age=23reward=80000)→ 不满足,跳过,不回表;
  • age=24reward=100000)→ 满足,回表,返回给 Server 层;
  • age=25reward=120000)→ 不满足,跳过,不回表。

🧩 执行器与引擎的关系

  • 执行器只管“要什么数据”;

  • 存储引擎负责“怎么取数据”。


⑦ 存储引擎层(Engine Layer)

InnoDB 为例(MySQL 默认引擎):

  1. 根据索引(B+ 树)定位数据页(Page)

  2. 如果数据页在 Buffer Pool(内存缓存),直接返回;

  3. 如果不在内存中,从磁盘加载到 Buffer Pool;

  4. 把对应行数据返回给执行器;

  5. 执行器拿到结果后,返回给客户端。

🧠 知识点:Buffer Pool

  • InnoDB 的数据按页(通常 16KB)为单位管理;

  • 缓存热数据,减少磁盘 I/O;

  • 类似于操作系统的页缓存机制。


🔍 三、整个执行流程图(简化版)

客户端│▼
连接器 → [查询缓存(已废弃)] → 解析器 → 预处理器 → 优化器 → 执行器│▼存储引擎(InnoDB)│▼磁盘数据 / Buffer Pool


🚀 四、性能优化角度总结

  1. 连接层优化:使用连接池,避免频繁创建连接。

  2. SQL 优化:查看执行计划(EXPLAIN),确认索引是否被使用。

  3. 索引优化:建立合适的联合索引、覆盖索引。

  4. 缓存优化:利用应用层缓存(Redis),减少频繁查询。

  5. 内存优化:调大 innodb_buffer_pool_size,让更多数据命中内存。


🧭 五、完整示例总结

以语句:

SELECT name FROM user WHERE id = 1;

整个过程如下:

  1. 客户端通过 TCP 连接到 MySQL;

  2. 连接器验证身份;

  3. SQL 进入解析器生成语法树;

  4. 预处理器验证表和列;

  5. 优化器确定使用主键索引;

  6. 执行器调用 InnoDB;

  7. InnoDB 在 Buffer Pool 查找对应页;

  8. 若页存在,直接返回;否则读磁盘;

  9. 执行器将结果返回客户端;

  10. 客户端接收并显示结果。

http://www.dtcms.com/a/490404.html

相关文章:

  • 专业的家居网站建设网站单页支付宝支付怎么做的
  • CC10-判断链表中是否有环
  • 【ZEGO即构开发者日报】谷歌推出新款视频生成模型 Veo 3.1;腾讯开源通用文本表示模型Youtu-Embedding;AI 陪伴赛道观察……
  • [Sora] 视频自动编码器(VAE) | `encode_``decode`
  • 算法沉淀第四天(Winner)
  • 西藏地图飞线html
  • 网站建设与管理课程代码做徽章标牌的企业网站
  • selenium实现自动化脚本的常用函数
  • 大语言模型,一个巨大的矩阵
  • 衡阳营养师报考网站大宗贸易交易平台
  • Azure API Management 负载均衡与故障转移策略完整指南
  • TI CCS软件安装
  • 内存映射文件
  • 网站开发开发语言企业网站做seo的优势
  • 资料片:R语言中常见的英文术语及其含义
  • 企业出海的挑战与应对方案
  • 架构术语:什么是东西流量和南北流量
  • 电子电器架构——车载网关转发buffer心得汇总
  • (Python)终端着色进阶:256色基础及色码效果展示
  • 《R for Data Science (2e)》免费中文翻译 (第10章) --- Exploratory data
  • 简述对网站进行评析的几个方面.wordpress 内涵
  • Python自动化从入门到实战(23):Python打地鼠游戏开发
  • (论文速读)ECLIPSE:突破性的轻量级文本到图像生成技术
  • dede 网站入侵新媒体h5是什么
  • 嵌入式系统守护者:复位IC详解与选型指南
  • 实战指南:用Cliproxy实现Reddit多账号安全运营的完整方案
  • Ovi-音视频生成模型
  • MySQL实战篇09:MySQL主从延迟压测-------每秒1000条写入,延迟1秒
  • 免费自助建站系统上海软件开发工资一般多少
  • 淘客网站做百度推广教育门户网站模板