SQL语句执行过程
SQL语句执行过程
MySQL架构
MySQL架构如下:

MySQL架构共分为两层:
- Server层:负责建立连接、分析和执行SQL。
- 存储引擎层:复杂数据的存储和提取。
MySQL的几个重要组件:
- 连接器:负责处理客户端连接。
- 查询缓存:缓存查询结果以提高性能。
- 解析器:解析SQL语句,生成查询计划。
- 优化器:优化查询计划以提高执行效率。
- 执行器:执行查询计划并返回结果。
连接器
连接器主要负责连接MySQL服务,然后才能执行SQL语句。
连接命令:
1 | mysql -h localhost -u root -p |
MySQL是基于TCP协议的,所以连接时需要经过TCP三次握手过程,断开连接时需要经过TCP四次挥手过程。
常用参数:
wait_timeout:空闲连接最大空闲时长,默认值为8小时。max_connections:最大连接数,默认值为151。
MySQL连接也分为长连接和短连接,但长连接有可能会占用内存过大导致MySQL服务异常重启。
解决办法:
- 定期断开长连接。
- 客户端主动重置连接。
连接器总结:
- 与客户端进行TCP三次握手建立连接。
- 校验客户端的用户名和密码,如果不对则报错。
- 如果对,读取该用户权限,后面的权限逻辑判断都基于此时的权限。
查询缓存
查询缓存以key-value的形式存储查询结果,key是SQL查询语句,value是查询结果。
但对于更新频繁的表,查询缓存的命中率较低,因为每次更新都会导致相关缓存被清空。
所以,MySQL8.0版本已经废弃了查询缓存功能。8.0之前的版本可以通过参数query_cache_type设置成DEMAND来关闭查询缓存。
解析器
解析器负责将SQL语句解析成MySQL能够理解的格式,生成查询计划。主要做两件事:
- 词法分析
- 语法分析
词法分析
词法分析将SQL语句分解成一个个的词法单元(token),每个token代表SQL语句中的一个基本元素,如关键字、标识符、操作符等。
如下SQL语句:
1 | select name from user; |
词法分析的结果如下:
| 关键字 | 非关键字 | 关键字 | 非关键字 |
|---|---|---|---|
| select | name | from | user |
语法分析
语法分析将词法分析的结果根据语法规则判断是否满足MySQL语法,没问题就会构建出SQL语法树,方便后续获取SQL类型、表名、字段名等信息。

注意:解析器只负责检查语法和构建语法树,不会去查表或者字段存不存在。
执行SQL
执行SQL主要分为三步:
- prepare阶段:预处理阶段。
- optimize阶段:优化阶段。
- execute阶段:执行阶段。
预处理器
prepare阶段主要做两件事:
- 检查SQL语句中的表或者字段是否存在。
- 将
select *中的*扩展为表上的所有列。
优化器
优化器主要负责确定SQL查询语句执行方案,比如选择哪个索引、使用什么连接方式等。
可以通过explain命令查看SQL语句的执行计划。
执行器
执行器根据优化器生成的执行计划来执行SQL语句,最终返回结果给客户端。
总结
执行一条SQL查询语句的过程如下:
-
连接器:建立连接,校验用户名和密码,读取权限。
-
查询缓存:如果查询缓存命中,则直接返回结果,否则继续执行。MySQL8.0版本已经废弃了查询缓存功能。
-
解析器SQL,通过解释器对SQL语句进行词法和语法分析,构建语法树。
-
执行SQL,共有三个阶段:
- 预处理阶段:检查表和字段是否存在,扩展
select *中的*。 - 优化阶段:确定SQL查询语句执行方案。
- 执行阶段:根据优化器生成的执行计划来执行SQL语句,最终返回结果给客户端。
- 预处理阶段:检查表和字段是否存在,扩展
-
查询语句的执行流程如下:权限校验(如果命中缓存)—>查询缓存—>分析器—>优化器—>权限校验—>执行器—>引擎
-
更新语句执行流程如下:分析器---->权限校验---->执行器—>引擎—redo log(prepare 状态)—>binlog—>redo log(commit 状态)
