解析器将sql文本转为语法树,仅做词法分析、语法分析和生成初始语法树,不执行、不校验语义或权限;如ordery by会报error 1064,a+b仅记为表达式节点。

MySQL 查询解析器干了什么
解析器负责把 SELECT * FROM users WHERE id = 1 这类文本 SQL 转成内部可识别的语法树(parse tree),不是直接执行,也不做权限或语义检查。
它只管三件事:词法分析(切分关键字、标识符、数字)、语法分析(验证是否符合 MySQL 语法规则)、生成初始语法树。
- 遇到
ORDER BY写成ORDERY BY,解析器立刻报错ERROR 1064 (42000),不进下一步 -
SELECT a+b FROM t中的a+b在这步只是被记为一个表达式节点,不计算值,也不查字段是否存在 - 解析器不关心表有没有索引、用户有没有权限——这些是后续模块的事
查询执行器真正干活的顺序
执行器拿到优化器输出的执行计划后,才开始调存储引擎接口取数据。它不解析 SQL,也不决定怎么查,只负责“按指令一步步跑”。
典型流程:open table → find index or full scan → read rows → filter WHERE → sort if needed → send result
请注意以下说明:1、本程序允许任何人免费使用。2、本程序采用PHP+MYSQL架构编写。并且经过ZEND加密,所以运行环境需要有ZEND引擎支持。3、需要售后服务的,请与本作者联系,联系方式见下方。4、本程序还可以与您的网站想整合,可以实现用户在线服务功能,可以让客户管理自己的信息,可以查询自己的订单状况。以及返点信息等相关客户利益的信息。这个功能可提高客户的向心度。安装方法:1、解压本系统,放在
- 即使
WHERE id = 1有索引,执行器仍要调用ha_innobase::index_read()或类似接口,由 InnoDB 层完成实际定位 - 如果
WHERE条件里有函数,比如WHERE YEAR(created_at) = 2023,执行器会在读出每行后调用函数计算,无法跳过无关行(除非函数能下推到引擎层) - 执行器会反复调用
handler::rnd_next()或handler::index_next(),直到返回HA_ERR_END_OF_FILE
为什么有时 explain 显示用了索引,但慢查询日志里 still doing 'Sending data'
因为 Sending data 状态在执行器阶段,表示正在从引擎读取并组装结果集——哪怕索引查找很快,但匹配行数巨大、或者需要回表、或者涉及临时表排序,都会卡在这步。
-
EXPLAIN的type: ref只说明索引查找方式,不代表最终扫描/返回行数少 - 执行器对每一行都要做字段提取、类型转换、字符集处理,大字段(如
TEXT)或宽表会让这步变慢 - 如果查询含
GROUP BY且无法利用索引排序,执行器会建内部临时表+文件排序,Creating sort index也会计入此状态
parser 和 executor 之间还有哪些关键中间环节
解析器输出语法树后,不会直接交给执行器。中间至少经过:预处理器(检查表/列是否存在)、优化器(重写查询、选择索引、生成执行计划)。
- 预处理器发现
SELECT * FROM nonexistent_table,报错ERROR 1146 (42S02),比解析器晚、比优化器早 - 优化器可能把
SELECT a FROM t WHERE a > 1 AND a 改写成 <code>SELECT a FROM t WHERE a BETWEEN 2 AND 9,执行器看到的是改写后的计划 - 执行器拿到的是
JOIN_TAB数组和访问方法(JT_ALL,JT_INDEX_SCAN等),不是原始 SQL
真正容易被忽略的是:解析器和执行器之间没有缓存,每次查询都重走全流程;而查询缓存(已弃用)或 Plan Cache(8.0.22+ 的 query_cache_type=OFF 下不可用)影响的是更上层,跟这两个模块本身无关。









