一条SELECT语句在MySQL底层究竟是如何流转并最终执行的?

落丽吖_7300

落丽吖_7300

2026-07-06

994人浏览

原创

mysql权限校验分两阶段:连接器在建连时校验用户身份并缓存权限,预处理器在解析后、优化前校验表/列级权限,执行器在调用引擎前再做字段级二次校验。

一条select语句在mysql底层究竟是如何流转并最终执行的?

连接器先校验权限,不是“连上就查”

客户端发起 mysql -h127.0.0.1 -uroot -p 或 JDBC 连接时,MySQL 并不直接处理 SQL,而是先走连接器流程:完成 TCP 三次握手、验证用户名密码、加载该用户的权限快照(注意:后续权限变更对已存在连接无效)。如果权限不足,会立刻报错 Access denied for user,根本不会进入后续阶段。

常见错误现象:明明在 mysql.user 表里改了权限,但应用仍报权限拒绝——大概率是复用的长连接没重连,也没调用 mysql_reset_connection() 重置上下文。

关键点:

  • 每个连接独享一套权限缓存,不随全局权限表实时刷新
  • 连接空闲超时由 wait_timeout 控制,默认 28800 秒(8 小时)
  • 连接器分配的是线程(或从线程池取),不是进程;高并发下线程数瓶颈比 CPU 更早出现

解析器和预处理器分两步拆解 SQL

SELECT name FROM user WHERE id = 1 这类语句,先被解析器做词法分析(切出 SELECT、name、FROM 等 token),再构建成语法树;接着预处理器介入,干三件事:检查 user 表是否存在、name 字段是否属于该表、当前用户是否有 SELECT 权限。任一失败,直接报错,比如 Unknown table 'user' 或 SELECT command denied to user。

容易踩的坑:

MySQL
MySQL

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

下载
  • * 在预处理阶段就被展开成实际列名,所以 SELECT * 的字段顺序、个数,完全取决于表定义那一刻的结构
  • 字段别名在预处理阶段不可见,SELECT a AS b WHERE b > 1 会报 Unknown column 'b'
  • 跨库查询如 SELECT * FROM db1.t1 JOIN db2.t2,预处理器会分别校验两个库的访问权限

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

优化器拿到合法的语法树后,核心任务是生成执行计划——它不关心你要什么结果,只关心哪条路径代价最低。比如 WHERE age > 25 AND status = 1,优化器可能选 status 索引(因选择性高),也可能全表扫描(若 status 只有两个值,索引区分度低)。

实操建议:

  • 用 EXPLAIN 看优化器选了哪个索引、是否用到覆盖索引、有没有 Using filesort
  • FORCE INDEX 能绕过优化器决策,但仅限调试;生产环境慎用,因为统计信息更新后可能反而更差
  • 复合索引字段顺序必须匹配 WHERE 中的最左前缀,INDEX(a,b,c) 对 WHERE b = 1 无效

执行器调存储引擎,但不直接读磁盘

执行器拿到优化器输出的执行计划后,开始逐行调用存储引擎接口。以 InnoDB 为例:它先查 Buffer Pool 是否有对应页,命中则直接返回;未命中才触发磁盘 I/O 加载页到内存。整个过程对 Server 层透明——执行器只管发指令,不关心数据在哪。

关键细节:

  • 执行器会做二次权限校验(比如某列被 SELECT 权限限制,但之前预处理只校验了表级权限)
  • LIMIT 是执行器层控制的,不是存储引擎层提前截断;即使最终只取 1 行,InnoDB 仍可能扫描多行后由执行器丢弃
  • 如果 SQL 涉及多个表,执行器按优化器指定的顺序驱动各表,驱动表(outer table)的每一行都会触发被驱动表(inner table)的一次索引查找或全表扫描

执行流程里最容易被忽略的,是预处理器和执行器这两层权限校验的分工:前者管“能不能查这张表”,后者管“能不能查这个字段”,中间还隔着一个优化器对执行路径的黑盒决策。很多权限问题卡在预处理,而性能问题往往藏在执行器与存储引擎的交互细节里。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

2023.10.12

4283

8

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

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

2023.10.27

891

4

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

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

2024.02.23

1109

5

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

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

2024.03.06

6181

10

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

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

2024.03.06

3043

4

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

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

2024.04.07

6160

11

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

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

2024.04.29

8321

6

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

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

2024.04.29

1130

5

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

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

2024.04.29

992

5

热门下载

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

精品课程

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

共1课时 | 187人学习