MySQL底层是如何将逻辑SQL转换为存储引擎可识别的操作的?

星芳君_2525

星芳君_2525

2026-07-18

900人浏览

原创

mysql执行sql需经连接器、分析器、优化器、执行器四层处理:连接器固化权限快照;分析器完成词法、语法、语义分析;优化器生成代价最优执行计划;执行器调用存储引擎api执行,innodb仅接收底层指令而非sql文本。

mysql底层是如何将逻辑sql转换为存储引擎可识别的操作的?

SELECT * FROM users WHERE id = 123 这类语句,MySQL 不是直接扔给 InnoDB 去查的。它必须先“翻译”一遍——把人类写的逻辑 SQL,变成存储引擎能听懂的、带具体访问路径和数据结构的操作指令。这个过程不是黑盒,而是由服务层(Server Layer)里几个关键组件接力完成的。

连接器做完权限快照后,分析器才真正开始读 SQL

连接建立后,权限信息就固化在当前连接线程的内存中,后续所有操作都基于这个快照判断——改了 mysql.user 表也无效,除非重连。分析器这时才接手 SQL 字符串,分三步走:

  • 词法分析:把 SELECT、FROM、users、WHERE、id、=、123 拆成独立 token,识别出关键字、表名、列名、常量
  • 语法分析:按 MySQL 语法规则组装成解析树(Parse Tree),确认结构合法,比如 SELECT 后不能跟 ORDER BY 而没 FROM
  • 语义分析:查 users 表是否存在、id 列是否属于该表、当前用户是否有 SELECT 权限——任一失败就报错,如 Unknown table 'users' 或 SELECT command denied to user

优化器决定“怎么查”,而不是“查什么”

解析树通过后,优化器登场。它不关心业务含义,只算代价:走主键索引查 1 行 vs 全表扫描 10 万行,哪个更省 IO 和 CPU?它会做这些事:

  • 逻辑重写:把 WHERE a = 1 AND b = 2 拆成独立条件,方便后续评估选择性
  • 索引评估:查 users 表的统计信息(如 INFORMATION_SCHEMA.STATISTICS),看 id 上有没有索引、选择性是否高(id 是主键,必然选它)
  • 执行路径决策:对单表查询,基本就是“用哪个索引 + 回表还是覆盖”;对多表 JOIN,还要选连接算法(NLJ / Hash Join / SMJ)和驱动表顺序
  • 生成执行计划:输出一个可执行的结构化指令序列,比如 “IndexScan on users using PRIMARY, filter: id = 123”

注意:优化器不会执行任何数据读取,它只输出计划。你可以用 EXPLAIN FORMAT=TREE SELECT * FROM users WHERE id = 123 看到它生成的完整决策树。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

执行器调用存储引擎接口,把计划变成真实动作

执行器拿到优化器的计划后,不再碰 SQL 文本,而是按指令调用存储引擎 API。对 InnoDB 来说,关键动作是:

  • 权限再检:虽然连接器已验权,但执行器在真正读表前还会校验一次,防止中间权限变更(尽管连接内权限不变,这是安全兜底)
  • 调用引擎接口:执行器调用 ha_innobase::index_read()(走索引)或 ha_innobase::rnd_next()(全表扫描),传入的是内部数据结构(如 KEY_PART_INFO 描述索引字段),不是原始 SQL
  • 处理结果集:引擎返回的是行数据缓冲区(record[]),执行器负责格式化(类型转换、NULL 处理)、应用 WHERE 剩余过滤(如果索引无法完全下推)、组装结果集
  • 事务上下文传递:如果当前会话开了事务,执行器会把事务 ID(trx_id)透传给 InnoDB,确保 MVCC 可见性判断正确

InnoDB 接收的是“定位+读取”指令,不是 SQL 字符串

InnoDB 完全不知道你写的是 SELECT 还是 UPDATE,它只接收执行器发来的底层操作请求。例如:

  • 主键等值查询 → 调用 btr_pcur_open_at_rnd_pos() 定位 B+ 树叶子页,再用 row_search_mvcc() 拿数据
  • 二级索引查询 → 先查二级索引 B+ 树得主键,再回表查聚簇索引 —— 这两步都是执行器拆解后分别调用的
  • INSERT → 执行器构造好记录 buffer,调 row_ins_clust_index_entry() 让 InnoDB 插入并维护锁和日志

真正的“翻译”终点在这里:SQL 的逻辑意图,最终被切片成一个个针对 B+ 树、undo log、buffer pool 的 C 函数调用。这也是为什么换存储引擎(比如 MyISAM)时,只要实现同一套 handler 接口,Server 层代码完全不用改。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4063

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

871

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1049

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5941

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2843

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5920

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7901

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1070

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

932

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 181人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 289人学习