分析器主要功能
分析器的位置
在 MySQL 的查询执行链路中,分析器(Parser)位于连接器之后、优化器之前。它的输入是SQL 字符串,输出是解析树(Parse Tree)。
graph LR
A[SQL字符串] --> B[分析器 Parser]
B --> C{词法分析}
C --> D{语法分析}
D --> E[解析树
Parse Tree]
E --> F[优化器]
两大核心功能
1. 词法分析(Lexical Analysis)
将 SQL 语句拆解成一个个”词法单元”(Token):
SELECT name, age FROM user WHERE id = 1;
词法分析结果:
| Token | 类型 |
|---|---|
| SELECT | 关键字 |
| name | 列名标识符 |
| , | 分隔符 |
| age | 列名标识符 |
| FROM | 关键字 |
| user | 表名标识符 |
| WHERE | 关键字 |
| id | 列名标识符 |
| = | 操作符 |
| 1 | 数字字面量 |
| ; | 结束符 |
2. 语法分析(Syntax Analysis)
根据 MySQL 语法规则,判断 Token 序列是否合法:
-- ✅ 合法
SELECT name FROM user WHERE id = 1;
-- ❌ 语法错误
SELECTT name FROM user WHERE id = 1;
-- ERROR 1064 (42000): You have an error in your SQL syntax...
-- ❌ 语句顺序错误
FROM user SELECT name;
-- ERROR 1064 (42000): You have an error in your SQL syntax...
语法分析生成解析树:
graph TD
Root[SELECT语句] --> Clause1[SELECT子句]
Root --> Clause2[FROM子句]
Root --> Clause3[WHERE子句]
Clause1 --> Col1[name列]
Clause1 --> Col2[age列]
Clause2 --> Table[user表]
Clause3 --> Condition[条件表达式]
Condition --> Left[id列]
Condition --> Op[=操作符]
Condition --> Right[1字面量]
分析器还做什么
表名和列名的预校验(MySQL 8.0+)
在 MySQL 8.0 中,分析器还会查询数据字典做语义预检查:
-- 如果表不存在,分析器就会报错
SELECT * FROM non_exist_table;
-- ERROR 1146 (42S02): Table 'test.non_exist_table' doesn't exist
注意:* 的展开(哪些列)是由后面的优化器或执行器完成的。
常见错误示例
-- 语法错误
SELECT * FORM user;
-- ERROR 1064: ...near 'FORM user'...
-- 关键字冲突(表名是关键字)
SELECT * FROM order;
-- 需要反引号包裹
SELECT * FROM `order`;
-- 不存在的函数
SELECT MY_CUSTOM_FUNC(id) FROM user;
-- 仅当函数不存在时才会报错
分析器与预编译
-- 预编译只做一次解析
PREPARE stmt FROM 'SELECT * FROM user WHERE id = ?';
-- 分析器在这里完成解析并生成解析树
-- 之后执行时跳过分析器
EXECUTE stmt USING @id;
预编译语句(Prepared Statement)的优势就在这里——解析只做一次,后续执行直接复用解析树。
性能影响
- 简单 SQL 的解析耗时在微秒级
- 复杂 SQL(多层子查询)可能到毫秒级
- 预编译可以消除重复解析开销
面试要点
- 输入输出:SQL 字符串 → 解析树
- 两个阶段:词法分析(拆 Token)→ 语法分析(建树)
- 报错时机:语法错误在分析器阶段报错,不是执行阶段
- 8.0 增强:部分语义检查也提前到分析器阶段
- 预编译关系:第一执行时解析,后续跳过
一句话总结:分析器是 MySQL 的”翻译官”,把人类写的 SQL 翻译成 MySQL 能理解的解析树。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容