MySQL执行流程详解

张开发
2026/4/14 13:25:34 15 分钟阅读

分享文章

MySQL执行流程详解
1.执行流程管理连接, 权限校验语法/词法分析生成语法树“选择「主键索引」为最优执行计划”是“命中缓存”否“缓存未命中”“客户端发送 SQL:SELECT * FROM user WHERE id 10”连接器分析器优化器执行器“InnoDB Buffer Pool中是否存在目标数据页?”“直接从Buffer Pool返回记录”“根据主键B树定位到叶子节点数据页”“从磁盘读取数据页加载到 Buffer Pool”“执行器将结果集返回给客户端”连接器客户端使用连接池技术来复用连接而 MySQL 服务端使用线程池技术来管理连接处理。连接器与客户端进行 TCP 三次握手建立连接校验客户端的用户名和密码如果用户名或密码不对则会报错如果用户名和密码都对了会读取该用户的权限然后后面的权限逻辑判断都基于此时读取到的权限解析器词法分析根据输入的字符串识别出关键字出来例如SQL 语句 select username from userinfo在分析之后会得到 4 个 Token其中有 2 个 Keyword分别为 select 和 from。语法分析根据词法分析的结果语法解析器会根据语法规则判断输入的这个 SQL 语句是否满足 MySQL 语法如果没问题就会构建出 SQL 语法树这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。如果我们输入的 SQL 语句语法不对会报错You have an eeror in your SQL syntax预处理器检查 SQL 查询语句中的表或者字段是否存在将select *中的*符号扩展为表上的所有列优化器优化器主要负责将 SQL 查询语句的执行方案确定下来比如在表里面有多个索引的时候优化器会基于查询成本的考虑来决定选择使用哪个索引。执行器主键索引查询存储引擎InnoDB的工作 - 核心步骤定位索引根页面InnoDB 引擎从数据字典中找到user表的主键索引聚簇索引的根页Root Page所在位置。B 树导航主键索引是一棵 B 树非叶子节点存储键值主键 ID和指向子页的指针叶子节点按顺序存储完整的行数据。引擎从根页开始使用二分查找法沿着id 10这个键值在 B 树中进行搜索。例如根页可能存有(5, P1), (20, P2)的指针那么10在5和20之间所以导航到P1指针指向的子页。如此递归直至找到对应的叶子节点页。访问缓冲池Buffer PoolInnoDB 不会直接读写磁盘。它首先在内存中的Buffer Pool里查找这个叶子节点页是否已经被缓存。如果缓存命中则直接在内存中获取数据。如果缓存未命中则需要发起一次I/O 操作从磁盘。ibd 文件中将包含id 10这行记录的整个数据页加载到 Buffer Pool 中。行记录获取在内存的数据页中引擎快速定位到id 10的这行记录并将其返回给上一层的执行器。执行器返回结果执行器从存储引擎拿到第一行也是唯一一行数据。在拿到数据后它还会根据 SQL 语句的SELECT *部分对这行记录做一次“格式化”例如字段的转换处理等本例中很简单。最终执行器将结果存入结果集通过连接返回给客户端。全表扫描在执行全表扫描时存在着大量的行数据复制-传递-丢弃的开销。存储引擎InnoDB的全表扫描循环关键点InnoDB 的全表扫描并不是杂乱无章地读取磁盘上的行。而是利用聚簇索引主键索引的叶子节点链表进行顺序扫描。定位起点执行器首次调用存储引擎接口时存储引擎会定位到聚簇索引 B 树最左边的叶子节点页即主键值最小的记录所在的页。顺序遍历叶子节点链表存储引擎将该页从磁盘加载到 Buffer Pool如果不在内存中。然后从该页的第一条记录开始依次读取每一条行记录。每读出一条记录就返回给执行器。页间跳转当一个数据页的所有记录都读完存储引擎会通过 B 树叶子节点间的双向链表指针找到下一个数据页继续同样的顺序读取过程。这个过程会一直持续直到遍历完整个叶子节点链表即扫描了表中的所有行。执行器的过滤与收集对于存储引擎返回的每一行数据执行器都会根据 SQL 语句中的WHERE age 30条件进行判断。如果条件满足执行器会将这行数据放入结果集。如果条件不满足执行器会丢弃这行数据。这个过程会持续到存储引擎返回 “没有更多数据了”即已扫描所有行。执行器返回结果当全表扫描循环结束后执行器将收集到的所有满足条件的行构成最终结果集返回给客户端。

更多文章