分析器主要功能

分析器主要功能

分析器的位置

在 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
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容