mysql将sql转为可执行指令需经词法分析→语法分析→语义分析三步:词法分析切分token并校验字符合法性;语法分析依据bison规则校验结构;语义分析检查对象存在性、权限及语义合规性。

MySQL怎么把一条SQL变成可执行的指令
MySQL不是直接运行你写的SQL字符串,而是先经过一套严格的解析流程,把文本转换成内部能理解的数据结构。这个过程决定了SQL是否合法、能否被优化、最终怎么执行。
核心环节分三步:词法分析 → 语法分析 → 语义分析(含权限与对象检查)。跳过任意一步,ERROR 1064 或 ERROR 1146 就可能出现。
词法分析阶段常见失败点
这一步由lex_yylex()函数驱动,把SQL字符串按规则切分成“token”(比如SELECT、`user_id`、123、=),遇到无法识别的字符或编码问题就直接报错。
- 中文全角符号(如“=”、“;”)会被当成非法token,触发
ERROR 1064 (42000): You have an error in your SQL syntax -
utf8mb4连接下混用latin1字段名,可能导致标识符解析失败 - 反引号包裹的名称里含控制字符(如
`user\u0000name`),部分版本会静默截断或报错
语法分析器如何判断SQL结构是否合法
MySQL用Bison生成的MYSQLparse()函数做语法校验,它依赖sql_yacc.yy定义的语法规则。写法稍有偏差,比如漏掉AS、在WHERE后跟ORDER BY而没加;(客户端层面)、子查询缺少别名,都会在这里卡住。
-
SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id WHERE t1.name = 'a' ORDER BY t2.id LIMIT 10—— 合法 -
SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id WHERE t1.name = 'a' ORDER BY t2.id LIMIT—— 缺少数值,ERROR 1064 -
SELECT (SELECT id FROM t2) FROM t1—— MySQL 5.7+允许,但5.6要求子查询必须有别名,否则报错
语义分析阶段才是真正“看懂”SQL的时候
语法对了不代表能跑。这一步检查表是否存在、列名是否拼写正确、用户是否有SELECT权限、函数是否支持(比如JSON_EXTRACT()在5.7+才可用)、聚合与非聚合字段是否混用等。
- 查一个不存在的库:
ERROR 1049 (42000): Unknown database 'xxx' - 字段名大小写敏感性取决于
lower_case_table_names配置,但列名默认不区分大小写——除非用反引号显式声明,此时严格匹配 -
SELECT user, COUNT(*) FROM mysql.user GROUP BY host在MySQL 8.0会报错,因为user不在GROUP BY中且非聚合字段(严格模式下)
真正容易被忽略的是:语法解析完成不代表执行计划已定——优化器在后续阶段才介入,所以EXPLAIN看到的执行路径,和解析阶段完全无关。










