第一次接触MySQL?一张图带你搞懂SQL语句的执行全流程

第一次接触MySQL?一张图带你搞懂SQL语句的执行全流程 文章目录[toc]第一次接触MySQL一张图带你搞懂SQL语句的执行全流程前言一、MySQL的总体架构先有个印象二、一条SQL的完整旅程步步拆解第1步连接器 —— 进门先验身份第2步查询缓存 —— MySQL 8.0之前的事第3步分析器 —— 听懂你在说什么3.1 词法分析3.2 语法分析第4步优化器 —— 找一条最优路径第5步执行器 —— 动手干活了第6步存储引擎 —— 真正跟数据打交道的人三、更新语句的额外步骤3.1 redo log重做日志—— 保证持久性3.2 binlog归档日志—— 保证可恢复性两阶段提交四、一张图总结全过程五、写给同样是初学者的你第一次接触MySQL一张图带你搞懂SQL语句的执行全流程作为一个刚接触MySQL的小白你是不是也好奇一条SQL语句敲下去背后到底发生了什么今天这篇文章带你一探究竟。前言刚开始学MySQL的时候我只会机械地敲SELECT FROM user WHERE id 1;这样的语句看到返回结果就完事了。但心里总有个疑问这背后到底是怎么工作的数据是怎么找到的为什么有时候查询快有时候慢如果你也有同样的疑惑这篇文章就是为你准备的。我会用大白话把一条SQL语句在MySQL中的完整执行流程讲清楚。一、MySQL的总体架构先有个印象在深入细节之前我们先看一眼MySQL的架构分层图┌─────────────────────────────────────────┐ │ 客户端 (Client) │ │ (命令行、Navicat、JDBC、应用程序...) │ └────────────────────┬────────────────────┘ │ SQL语句 ▼ ┌─────────────────────────────────────────┐ │ 连接器 (Connection Pool) │ │ 负责建立连接、权限验证、连接管理 │ └────────────────────┬────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ 服务层 (Server Layer) │ │ ┌─────────────────────────────────┐ │ │ │ 查询缓存 (8.0已废弃) │ │ │ └─────────────────────────────────┘ │ │ ┌─────────────────────────────────┐ │ │ │ 分析器 (解析预处理) │ │ │ └─────────────────────────────────┘ │ │ ┌─────────────────────────────────┐ │ │ │ 优化器 (Optimizer) │ │ │ └─────────────────────────────────┘ │ │ ┌─────────────────────────────────┐ │ │ │ 执行器 (Executor) │ │ │ └─────────────────────────────────┘ │ └────────────────────┬────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ 引擎层 (Storage Engine) │ │ InnoDB MyISAM Memory ... │ └─────────────────────────────────────────┘简单理解服务层负责你想干什么引擎层负责数据怎么存、怎么取。咱们常用的InnoDB是默认引擎也是最重要的一种。二、一条SQL的完整旅程步步拆解假设我们执行一条最简单的查询SELECTname,ageFROMuserWHEREid10;这条语句在MySQL内部经历了怎样的旅程呢我们一步步来看。第1步连接器 —— 进门先验身份在你执行任何SQL之前首先得和MySQL建立连接mysql-h127.0.0.1-P3306-uroot-p连接器负责建立TCP连接三次握手验证用户名和密码检查该用户拥有的权限对哪些库、哪些表有什么操作权限⚠️ 注意权限是在连接时读取的连接期间即使管理员修改了你的权限也不会影响当前连接除非你重新连接。连接建立后如果长时间没有操作连接器会在wait_timeout默认8小时后自动断开。第2步查询缓存 —— MySQL 8.0之前的事先说结论如果你是MySQL 8.0这一层直接跳过因为查询缓存被彻底移除了。在8.0之前的版本MySQL收到查询请求后会先查缓存。以SQL语句为key之前查询的结果为value如果能命中就直接返回。为什么被废弃 因为缓存的失效非常频繁——只要表有更新这个表的所有缓存就全部清空。对于频繁更新的表缓存命中率极低维护成本却很高得不偿失。第3步分析器 —— 听懂你在说什么MySQL需要理解你写的SQL到底是什么意思这一步分两个阶段3.1 词法分析把你的SQL拆成一个个有意义的单词TokenSELECT → 关键字表示查询操作 name, age → 字段名 FROM → 关键字表示从哪个表 user → 表名 WHERE → 关键字表示过滤条件 id 10 → 条件表达式3.2 语法分析根据MySQL的语法规则检查这些Token组成的语句是否符合SQL语法-- 比如你写错了SELECTFORMuser;-- FORM拼写错误-- MySQL会直接报错ERROR1064You have an errorinyourSQLsyntax...语法检查通过后MySQL会生成一棵语法树AST供后续步骤使用。第4步优化器 —— 找一条最优路径优化器是整个流程中最“聪明”的一环。它就问你一个问题到达同样的目的地哪条路最近比如我们的查询WHERE id 10假设id上有主键索引。优化器会决定是直接用主键索引快速定位到那一行还是全表扫描一行一行比对显然用索引快得多优化器会选择索引。再比如你的表上有多个索引或者涉及到多表JOIN先查哪个表、用哪个索引都是优化器说了算。-- 你可以通过 EXPLAIN 来查看优化器的决策EXPLAINSELECTname,ageFROMuserWHEREid10;第5步执行器 —— 动手干活了优化器定了方案执行器就按这个方案去执行。执行前还会再做一次权限校验看看你对user表有没有查询权限。对于WHERE id 10这条语句执行流程大致是调用引擎接口取id 10这一行判断这一行是否满足条件如果还有别的条件的话满足就放入结果集否则跳过把所有满足的行收集起来返回给客户端第6步存储引擎 —— 真正跟数据打交道的人执行器不直接操作磁盘而是通过调用存储引擎的API来读取数据。以InnoDB为例从磁盘读取数据的过程涉及Buffer Pool缓冲池先查内存没有再读磁盘B树索引通过主键索引快速定位数据所在的页数据页InnoDB以页为单位读取数据默认每页16KB这部分展开会很多我会在后续的文章里专门讲InnoDB的索引和存储结构欢迎关注~三、更新语句的额外步骤上面讲的是查询那如果是更新语句呢比如UPDATEuserSETage20WHEREid10;它除了要经历上面所有步骤还多了两个关键角色3.1 redo log重做日志—— 保证持久性InnoDB独有属于物理日志记录“在哪个数据页上做了什么修改”。作用如果数据库突然崩溃重启后可以通过redo log恢复未写入磁盘的数据。它的写入方式是循环写固定大小写满了就擦除旧的。3.2 binlog归档日志—— 保证可恢复性Server层共有属于逻辑日志记录“对哪个表的哪一行做了什么操作”。作用主从复制、数据恢复。比如你想恢复到某个时间点的数据就可以用binlog。它的写入方式是追加写文件写满了就切换下一个。两阶段提交为了保证redo log和binlog的一致性InnoDB使用了两阶段提交Prepare阶段写入redo log标记为prepare写binlogCommit阶段将redo log标记为commit这样即使在任何一步发生崩溃重启后也能判断事务到底要不要提交。四、一张图总结全过程客户端发送SQL │ ▼ 连接器 ─── 验证身份、权限 │ ▼ 查询缓存 ─── (8.0已废弃) 有缓存直接返回 │ ▼ 分析器 ─── 词法分析 → 语法分析 → 语法树 │ ▼ 优化器 ─── 选索引、定Join顺序、生成执行计划 │ ▼ 执行器 ─── 权限校验 → 调用引擎接口 → 返回结果 │ ▼ 存储引擎 ─── 数据读写内存Buffer Pool磁盘五、写给同样是初学者的你作为一个刚上路的新手我的建议是别死记硬背先理解每个组件是干什么的有个整体脉络就好多用 EXPLAIN慢慢就能看懂优化器是怎么决策的从InnoDB开始这是最常用的引擎深入它就对了一半后续可以逐步深入索引原理、事务隔离级别、锁机制、日志系统……MySQL的水很深但一步步来并不难。希望这篇文章能帮你建立起对MySQL执行流程的整体认知。这是我的第一篇MySQL学习笔记如果对你有帮助欢迎点赞、收藏~有不对的地方也请大佬们指正手我的建议是别死记硬背先理解每个组件是干什么的有个整体脉络就好多用 EXPLAIN慢慢就能看懂优化器是怎么决策的从InnoDB开始这是最常用的引擎深入它就对了一半后续可以逐步深入索引原理、事务隔离级别、锁机制、日志系统……MySQL的水很深但一步步来并不难。希望这篇文章能帮你建立起对MySQL执行流程的整体认知。