MySQL执行流程详解

1.执行流程

管理连接, 权限校验
语法/词法分析

生成语法树
"选择「主键索引」

为最优执行计划"
是"命中缓存"
否"缓存未命中"
"客户端发送 SQL:

SELECT * FROM user WHERE id = 10"
连接器
分析器
优化器
执行器
"InnoDB Buffer Pool

中是否存在目标数据页?"
"直接从Buffer Pool

返回记录"
"根据主键B+树

定位到叶子节点数据页"
"从磁盘读取数据页

加载到 Buffer Pool"
"执行器将结果集

返回给客户端"

连接器

客户端使用连接池技术来复用连接,而 MySQL 服务端使用线程池技术来管理连接处理。

连接器:

  • 与客户端进行 TCP 三次握手建立连接;

  • 校验客户端的用户名和密码,如果用户名或密码不对,则会报错;

  • 如果用户名和密码都对了,会读取该用户的权限,然后后面的权限逻辑判断都基于此时读取到的权限;

解析器

  1. **词法分析:**根据输入的字符串识别出关键字出来,例如,SQL 语句 select username from userinfo,在分析之后,会得到 4 个 Token,其中有 2 个 Keyword,分别为 select 和 from。

  2. 语法分析: 根据词法分析的结果,语法解析器会根据语法规则,判断输入的这个 SQL 语句是否满足 MySQL 语法,如果没问题就会构建出 SQL 语法树,这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。如果我们输入的 SQL 语句语法不对,会报错:You have an eeror in your SQL syntax;

预处理器

  • 检查 SQL 查询语句中的表或者字段是否存在;

  • select * 中的 * 符号,扩展为表上的所有列;

优化器

优化器主要负责将 SQL 查询语句的执行方案确定下来,比如在表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引。

执行器

  1. 主键索引查询

存储引擎(InnoDB)的工作 - 核心步骤

  • 定位索引根页面 :InnoDB 引擎从数据字典 中找到 user 表的主键索引(聚簇索引)的根页(Root Page)所在位置。

  • B+ 树导航

    • 主键索引是一棵 B+ 树,非叶子节点存储键值(主键 ID)和指向子页的指针,叶子节点按顺序存储完整的行数据。

    • 引擎从根页开始,使用二分查找法,沿着 id = 10 这个键值在 B+ 树中进行搜索。

    • 例如,根页可能存有 (5, P1), (20, P2) 的指针,那么 10520 之间,所以导航到 P1 指针指向的子页。如此递归,直至找到对应的叶子节点页

  • 访问缓冲池(Buffer Pool)

    • InnoDB 不会直接读写磁盘。它首先在内存中的 Buffer Pool 里查找这个叶子节点页是否已经被缓存。

    • 如果缓存命中,则直接在内存中获取数据。

    • 如果缓存未命中 ,则需要发起一次 I/O 操作 ,从磁盘(。ibd 文件)中将包含 id = 10 这行记录的整个数据页加载到 Buffer Pool 中。

  • 行记录获取 :在内存的数据页中,引擎快速定位到 id = 10 的这行记录,并将其返回给上一层的执行器

执行器返回结果

  • 执行器从存储引擎拿到第一行(也是唯一一行)数据。

  • 在拿到数据后,它还会根据 SQL 语句的 SELECT * 部分,对这行记录做一次"格式化"(例如,字段的转换处理等,本例中很简单)。

  • 最终,执行器将结果存入结果集,通过连接返回给客户端。

  • 全表扫描:在执行全表扫描时,存在着大量的行数据"复制-传递-丢弃"的开销。

存储引擎(InnoDB)的全表扫描循环关键点 :InnoDB 的全表扫描,并不是杂乱无章地读取磁盘上的行。而是利用聚簇索引(主键索引)的叶子节点链表 进行顺序扫描

  • 定位起点 :执行器首次调用存储引擎接口时 ,存储引擎会定位到聚簇索引 B+ 树最左边的叶子节点页(即主键值最小的记录所在的页)。

  • 顺序遍历叶子节点链表

    1. 存储引擎将该页从磁盘加载到 Buffer Pool(如果不在内存中)。

    2. 然后从该页的第一条记录开始,依次读取每一条行记录

    3. 每读出一条记录,就返回给执行器。

  • 页间跳转 :当一个数据页的所有记录都读完,存储引擎会通过 B+ 树叶子节点间的双向链表指针,找到下一个数据页,继续同样的顺序读取过程。这个过程会一直持续,直到遍历完整个叶子节点链表,即扫描了表中的所有行。

执行器的过滤与收集:

  • 对于存储引擎返回的每一行数据 ,执行器都会根据 SQL 语句中的 WHERE age > 30 条件进行判断。

  • 如果条件满足,执行器会将这行数据放入结果集。

  • 如果条件不满足,执行器会丢弃这行数据。

  • 这个过程会持续到存储引擎返回 "没有更多数据了"(即已扫描所有行)。

执行器返回结果

  • 当全表扫描循环结束后,执行器将收集到的所有满足条件的行构成最终结果集,返回给客户端。
相关推荐
2601_962066491 小时前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
愤怒的苹果ext2 小时前
MySQL Shell备份恢复数据库
数据库·mysql·备份恢复·mysqlsh
数字新视界4 小时前
DCIM管理系统的技术架构与部署模式详解
数据库·物联网·数据中心·数据中心基础设施管理·dcim管理系统
何以解忧,唯有..4 小时前
Pydantic 介绍与使用:Python 数据校验的现代方案
数据库·python·microsoft
超兔一体云5 小时前
MySQL索引优化实战——从慢查询到索引调优
后端·mysql
这个DBA有点耶5 小时前
数据库容灾进入“秒级时代”:同城双活架构原理、关键技术选型与落地实践
数据库·架构·dba
2601_962074816 小时前
大数据-264 实时数仓 - Canal MySQL的binlog研究 存储目录 变动信息 配置MySQL
大数据·数据库·mysql
2601_962073816 小时前
大数据-240 离线数仓 - 广告业务 测试 ADS层数据加载 DataX数据导出到 MySQL
大数据·数据库·mysql
Frank_refuel7 小时前
【MYSQL进阶】-> 索引理解
数据库
lv__pf7 小时前
MVCC机制【TL mysql7】
数据库