MySQL 一条 SQL 的执行流程是什么?
简化版
MySQL 执行一条 SQL 通常经过连接器、解析器、预处理、优化器、执行器和存储引擎:先建立连接并校验语法,再生成执行计划,最后由执行器调用存储引擎读写数据。
详细版
以 SELECT * FROM users WHERE id = 1 为例,客户端先和 MySQL 建立连接并完成权限认证;解析器把 SQL 解析成语法结构;预处理阶段检查表和列是否存在;优化器选择索引和连接顺序;执行器按照执行计划调用 InnoDB 接口读取数据;结果再返回给客户端。
面试里要区分 MySQL Server 层和存储引擎层。Server 层负责 SQL 解析、优化、执行控制,InnoDB 负责索引、数据页、锁、事务、日志等底层能力。
对于更新语句,还会涉及 undo log、redo log、binlog 和两阶段提交。不同 SQL 的细节不同,但“连接 -> 解析 -> 优化 -> 执行 -> 引擎”的主线不变。
完整版教学
一、先看整体链路
MySQL 执行流程可以画成一条主线:
客户端
-> 连接器
-> 解析器
-> 预处理
-> 优化器
-> 执行器
-> 存储引擎
-> 返回结果
这个链路说明 MySQL 不是拿到 SQL 就直接去磁盘找数据。它先理解 SQL,再决定怎么执行,最后才调用存储引擎。
记忆钩子:SQL 先被“看懂”,再被“选路”,最后才被“执行”。
二、连接器负责认证和连接上下文
客户端连接 MySQL 时,连接器负责认证用户、检查密码、建立连接上下文。
mysql -h 127.0.0.1 -u app -p
连接建立后,MySQL 会维护这个会话的用户身份、权限、系统变量、事务状态等。比如同一个连接里执行:
SET autocommit = 0;
SELECT @@autocommit;
这类会话变量会影响后续 SQL。长连接过多会占用内存,连接池配置不合理也会让数据库压力上升。
三、解析器和预处理做什么
解析器会做词法和语法分析,把 SQL 拆成数据库能理解的结构。
SELECT id, name FROM users WHERE id = 1;
它会识别 SELECT、字段、表名、条件等元素。如果写成 SELEC id FROM users,语法阶段就会报错。
预处理阶段会进一步检查表是否存在、字段是否存在、权限是否满足等。例如:
SELECT not_exists_col FROM users;
字段不存在时,不需要进入真正执行阶段就能报错。
四、优化器选择执行计划
优化器负责在多个可能路径中选择成本较低的执行计划,比如是否走索引、走哪个索引、表连接顺序如何。
SELECT *
FROM orders
WHERE user_id = 10
AND status = 'paid';
如果有两个索引:
idx_user_id(user_id)
idx_status(status)
优化器会根据统计信息估算哪个索引过滤性更好。若 user_id=10 只有 20 行,而 status='paid' 有 100 万行,它大概率选择 idx_user_id。
优化器不是永远完美,统计信息过旧、条件复杂或数据倾斜时可能选错执行计划,所以慢查询排查常需要 EXPLAIN。
五、执行器如何调用存储引擎
执行器拿到执行计划后,会按计划调用存储引擎接口。对于 InnoDB 来说,真正的索引查找、行读取、锁、MVCC 判断都在引擎层完成。
主键查询可以简化成:
执行器:我要 id=1 的行
InnoDB:沿主键 B+ 树查找
InnoDB:根据事务可见性判断记录版本
执行器:拿到行后返回给客户端
如果查询需要过滤很多行,执行器可能一边从引擎取行,一边判断 Server 层条件。不同条件能否下推到引擎,会影响扫描和返回成本。
六、更新语句会牵涉日志
更新语句除了执行流程主线,还要保证事务和复制一致性。
UPDATE users SET age = age + 1 WHERE id = 1;
简化流程:
定位记录
-> 生成 undo log 便于回滚
-> 修改 Buffer Pool 中的数据页
-> 写 redo log 保证崩溃恢复
-> 写 binlog 用于复制和恢复
-> 提交事务
InnoDB redo log 和 MySQL Server 层 binlog 之间通过两阶段提交协调,避免崩溃后存储引擎数据和 binlog 不一致。
七、常见误区与追问
- 误区:MySQL Server 层直接管理所有数据页。 数据页、索引、锁和事务主要由 InnoDB 这类存储引擎负责。
- 误区:解析通过后 SQL 就直接执行。 中间还有预处理、优化器选计划等步骤。
- 误区:优化器一定选最优索引。 它基于统计信息估算成本,数据倾斜或统计过旧时可能选错。
- 误区:SELECT 和 UPDATE 流程完全一样。 更新还涉及 undo、redo、binlog 和提交一致性。
- 追问:Explain 看的是哪个阶段结果? 主要是优化器选择出的执行计划信息。
- 追问:为什么存储引擎可替换? MySQL Server 层和存储引擎层分离,统一接口下可以接不同引擎。
八、加强记忆
执行流程题用“连、解、查、优、执、引擎”串起来:连接认证,解析 SQL,检查表列权限,优化器选路,执行器调引擎,引擎读写数据。遇到更新语句,再补上 undo、redo、binlog 和两阶段提交。