查询语句select执行流程,如下图所示,其核心流程可概括为:
flowchart TD
A["客户端提交 SELECT 语句"] --> B["连接器<br>管理连接, 权限验证"]
B --> C["查询缓存<br>(MySQL 8.0+已移除)<br>命中则直接返回"]
C --> D["解析器<br>语法分析, 生成解析树"]
D --> E["预处理器<br>语义检查, 对象/权限验证"]
E --> F["优化器<br>生成最优执行计划"]
F --> G["执行器<br>调用存储引擎接口执行计划"]
G --> H["存储引擎<br>(InnoDB)<br>执行索引查找/数据读取"]
H --> I["返回结果集至客户端"]
核心组件阶段
1. 连接器 (Connector)
- 职责:管理客户端连接、身份认证和权限校验。
- 流程:客户端发起连接,连接器验证用户名、密码和主机权限。验证通过后,会建立连接并管理该连接的所有状态。如果该用户权限有变更,已在线的连接不会受影响,需重新建立连接才能生效。
2. 查询缓存 (Query Cache) - (MySQL 8.0+已移除)
- 职责:缓存完整的查询结果(Key-Value形式,Key是查询SQL,Value是结果集)。
- 流程:如果命中缓存,结果直接返回给客户端。但由于任何表的数据更新都会导致该表的所有缓存失效,在频繁写的场景下缓存命中率极低,且管理和检查缓存带来额外开销,因此该功能在 MySQL 8.0 中被彻底移除。
3. 解析器 (Parser)
- 职责:进行词法分析和语法分析。
- 流程:
- 词法分析:将完整的SQL语句拆分成一个个的“词元”(Token),例如识别
SELECT
、FROM
、表名
、列名
等。 - 语法分析:根据MySQL的语法规则,检查这些词元组合成的SQL语句是否符合规范。如果语法错误(如缺少关键字),会在此阶段抛出错误。解析通过后,会生成一棵解析树(Abstract Syntax Tree)。
- 词法分析:将完整的SQL语句拆分成一个个的“词元”(Token),例如识别
4. 预处理器 (Preprocessor) / 解析器后续阶段
- 职责:进行语义检查。
- 流程:基于解析树进行进一步验证:
- 检查表和列名是否存在。
- 检查
WHERE
子句中的字段是否合法。 - 对
*
进行展开为所有具体列名。 - 检查用户对相关对象的访问权限。
- 进行一些简单的逻辑优化(如常量折叠)。
5. 优化器 (Optimizer)
- 职责:将解析树转换为最优的执行计划。这是最复杂也是最关键的环节。
- 决策内容:
- 选择访问路径:应该使用哪个索引?还是全表扫描?例如,
WHERE id = 5
,如果id
有索引,优化器会决定是使用主键索引还是二级索引。 - 选择连接顺序和算法:对于多表连接(JOIN),决定先读哪张表,以及使用哪种连接算法(Nested-Loop Join, Hash Join, etc.)。
- 子查询优化:尝试将子查询转换为更高效的
JOIN
操作。 - 条件简化:对
WHERE
和HAVING
子句中的条件进行简化。 - 优化器基于成本模型(Cost Model)进行决策,它会估算各种执行方式的 I/O、CPU、内存等开销,选择“成本”最低的那个计划。
- 选择访问路径:应该使用哪个索引?还是全表扫描?例如,
6. 执行器 (Executor)
- 职责:根据优化器生成的执行计划,调用存储引擎提供的接口来执行查询。
- 流程:
- 在执行前,先检查用户对表是否有执行权限(如果启用了查询缓存,权限检查可能在缓存前进行)。
- 根据计划的指示,循环调用存储引擎接口:
- 从第一行开始,调用存储引擎的“读下一行”接口。
- 存储引擎通过索引或扫描找到数据并返回给执行器。
- 执行器根据
WHERE
子句条件进行过滤。 - 将符合条件的数据行放入结果集中。
- 执行器完成后,将结果集返回给客户端。
7. 存储引擎 (Storage Engine) - 以 InnoDB 为例
- 职责:真正负责数据的存储和提取。执行器发出的指令最终由存储引擎执行。
- 流程(以索引查找为例):
- 定位根节点:从索引的根页(Root Page)开始。
- 遍历非叶子节点:在 B+Tree 的非叶子节点层进行二分查找,确定目标数据所在的下层页(指针)。
- 定位叶子节点:不断向下遍历,直到找到包含目标数据的叶子节点页。
- 在叶子节点中查找:
- 等值查询:在叶子节点内使用二分查找定位到精确的记录。
- 范围查询:找到范围的起始点,然后沿着叶子节点间的双向链表向后(或向前)扫描,直到范围结束。
- 返回记录:将找到的记录返回给执行器(如果是“覆盖索引”,则直接从索引中返回数据,否则需要根据主键ID回表查询主索引获取完整数据行)。