查询执行器是SQL语句真正执行的环节,负责按执行计划调用存储引擎接口获取数据、校验权限、逐节点过滤连接聚合,并返回结果集,不解析SQL、不选索引、不缓存、不写binlog。

查询执行器是SQL语句真正“干活”的环节,它不负责判断对错、也不决定怎么快,而是按优化器生成的执行计划,一步步把数据从存储引擎中取出来、过滤、连接、聚合,最后组装成结果集返回。
执行器的核心职责
执行器本身不读磁盘或管理索引,它是一个调度与协调层:
- 校验用户对涉及表、列的访问权限(第二次权限检查,区别于连接器的初始权限加载)
- 调用存储引擎接口(如InnoDB的
ha_innobase::index_read或ha_innobase::rnd_next)获取数据行 - 按执行计划逐节点执行:比如先扫描users表,再对每行匹配WHERE条件,再关联orders表,最后计算SUM
- 将符合条件的行逐步写入内部缓冲区,最终拼成结果集发送给客户端
它如何与存储引擎协作
执行器与引擎之间通过统一的handler API通信,屏蔽底层差异:
- 对InnoDB表,执行器发出“按主键查找id=100”指令,InnoDB在B+树中定位并返回记录
- 对MyISAM表,执行器调用“全表扫描”,MyISAM按数据文件物理顺序逐行读取
- 若查询含ORDER BY但无可用索引,执行器会在内存或临时磁盘文件中做归并排序
- 遇到LIMIT 10,执行器在拿到第10行后主动终止后续读取,避免冗余IO
执行过程中的关键行为
执行器不是黑箱,它的行为直接影响性能和结果一致性:
- 每行数据从引擎返回后,立即应用WHERE条件过滤;不满足的行不会进入后续JOIN或GROUP BY阶段
- 对于子查询(如
WHERE id IN (SELECT ...)),执行器可能选择物化为临时表,或改写为JOIN执行 - 若需访问被其他事务修改但未提交的数据,执行器会依据当前隔离级别(如REPEATABLE READ)请求引擎提供一致性视图
- 执行过程中发生锁等待(如行锁冲突),执行器会暂停并进入等待队列,超时则报Deadlock或Lock wait timeout
注意:它不缓存、不解析、不决策
执行器严格遵循上游输出:
- 它不重新解析SQL——语法和语义已在分析器和预处理器阶段完成
- 它不决定走哪个索引——那是优化器输出的执行计划已明确指定访问路径
- 它不维护查询缓存——MySQL 8.0起该模块已被移除,执行器不再参与缓存逻辑
- 它不写binlog——那是Server层日志模块在执行器提交后单独触发的










