error 1064即解析器拒绝解析,因其仅做词法与语法检查,不查表、不验权限;常见于拼写错误、缺条件、多符号等导致token流断裂或语法树无法构建的情况。

怎么确认SQL是否被解析器拒绝
解析器只管语法和基础语义,不查表是否存在、字段有没有权限——这些是预处理器和执行器的事。所以当你看到类似 ERROR 1064 (42000) 这类错误,基本就是解析器在词法或语法分析阶段直接拦下的。
常见触发点包括:
-
SELECT * FORM users(FORM拼错,词法识别失败) -
SELECT id, name FROM users WHERE;(WHERE后缺条件,语法树无法闭合) -
SELECT 1 + 'abc' + ;(末尾多一个+,Token流断裂)
这类错误不会进入优化器,也不会查任何表,响应极快。只要报错信息里带 near 关键字并指向某处字符位置,基本可断定卡在解析器。
如何观察解析器输出的语法树结构
MySQL 不对外暴露完整 AST,但可通过 EXPLAIN FORMAT=TREE 或调试模式间接窥见解析结果。真正能反映解析器意图的是 SHOW WARNINGS 配合 parser_trace 系统变量(需开启)。
实操步骤:
- 执行
SET SESSION optimizer_trace="enabled=on,one_line=off"; - 运行目标 SQL,比如
SELECT id FROM users WHERE age > 25 ORDER BY id LIMIT 5; - 查
SELECT * FROM information_schema.OPTIMIZER_TRACE;,其中steps字段里会包含"join_preparation"和"join_optimization"前的原始解析结构,例如字段名列表、WHERE 条件表达式树节点
注意:parser_trace 是内部调试开关,生产环境慎开;且 MySQL 8.0+ 中部分解析细节已收敛进优化器流程,不再单独输出 Token 流。
为什么有些合法SQL在解析器阶段就报错,而另一些看似更“错”的却能过
解析器遵循严格语法定义,但 MySQL 的 SQL 方言存在历史兼容性让步。比如:
-
SELECT * FROM t1, t2 WHERE t1.id = t2.id;能过,因为逗号连接是标准语法(尽管不推荐) -
SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id WHERE 1;也能过,WHERE 1是合法布尔表达式 - 但
SELECT * FROM t1 GROUP BY id HAVING COUNT(*) > 1 ORDER BY name;在 MySQL 5.7 strict mode 下可能被预处理器拦截(name不在 GROUP BY 或聚合函数中),而非解析器
关键区别在于:解析器只判断「能不能切成有效 Token 并组成合法语法树」,不判断「语义是否符合 SQL 标准或当前 SQL_MODE」。后者由后续阶段处理。
解析器对大小写和空格敏感吗
词法分析阶段,关键字(如 SELECT、FROM)不区分大小写,但标识符(表名、列名)是否敏感取决于 lower_case_table_names 和字符集 collation 设置;空格只作为 Token 分隔符,不影响解析逻辑。
典型陷阱:
-
SELECT*FROMusers(无空格)仍能被识别为SELECT+*+FROM+users,因为词法分析器靠字符类型切分,不是靠空格 -
SELECT `user.name` FROM users中反引号包裹的标识符会被整体识别为一个 Token,中间的点不会被当作操作符解析 - 但
SELECT user.name FROM users会被拆成user、.、name三个 Token,再由语法分析器组合为列引用
真正容易翻车的是引号嵌套错误,比如单引号内又出现未转义的单引号,会导致 Token 截断,直接触发 ERROR 1064。











