SELECT 语句的执行过程涉及 逻辑执行顺序 和 物理处理流程 两个维度。以下结合 MySQL 等主流数据库的实现机制,分阶段详细解析:
一、逻辑执行顺序(SQL 语句的解析逻辑)
SQL 语句的书写顺序与数据库内部执行顺序不同,其核心逻辑顺序如下(以复杂查询为例):
- FROM 和 JOIN
- 确定主表或初始数据集,处理多表连接(如 JOIN、LEFT JOIN)。笛卡尔积生成:先对表进行交叉连接生成临时虚表(VT1-J1)。ON 条件过滤:根据连接条件筛选行(VT1-J2)。外部行添加(仅限外连接):补充未匹配行的 NULL 值(VT1-J3)。
- WHERE 条件过滤
- 对连接后的虚表逐行应用 WHERE条件,过滤掉不满足条件的行(生成 VT2)。
- GROUP BY 分组
- 按指定列分组,生成分组结果(VT3)。聚合函数计算:如 SUM()、COUNT(),但需在 HAVING前完成。
- HAVING 分组后过滤
- 对分组后的结果应用聚合条件(如 HAVING COUNT(*) > 5),生成 VT4。
- SELECT 列投影
- 选择需要返回的列,处理表达式和别名(生成 VT5)。DISTINCT 去重:移除重复行(生成 VT6)。
- ORDER BY 排序
- 对最终结果按指定列排序(生成 VT7)。
- LIMIT 分页
- 截取指定行数返回(生成最终结果 VT8)。
示例:
SELECT dept_id, AVG(salary)
FROM employees e
JOIN departments d ON e.dept_id = d.id
WHERE salary > 50000
GROUP BY dept_id
HAVING AVG(salary) > 60000
ORDER BY AVG(salary) DESC
LIMIT 5;
执行顺序:FROM → JOIN → ON → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT。
二、物理处理流程(MySQL 的内部机制)
数据库处理查询的物理流程分为以下阶段:
1. 客户端连接与权限验证
- 连接建立:通过 TCP/IP 或 Unix Socket 建立连接,验证用户名/密码。
- 权限检查:确认用户对表/列的访问权限(如 SELECT权限)。
2. 查询解析与预处理
- 词法分析:将 SQL 拆解为关键字(如 SELECT、FROM)、表名、列名等标记。
- 语法分析:检查 SQL 是否符合语法规则(如缺少 WHERE条件是否合法)。
- 语义分析:验证表/列是否存在,处理别名和子查询。
3. 查询优化
- 逻辑优化:重写查询(如将 IN子查询转为 JOIN)。确定表连接顺序(基于统计信息估算成本)。
- 物理优化:选择索引(如 age列的 B+ 树索引)。决定全表扫描或索引扫描。
4. 执行计划生成
- 生成 EXPLAIN可展示的执行计划,包含访问类型(type)、扫描行数(rows)等关键指标。
5. 存储引擎交互
- 数据读取:使用索引(如主键索引、二级索引)快速定位数据。无索引时触发全表扫描(All类型)。
- 聚合与过滤:存储引擎返回原始数据后,SQL 层执行 WHERE过滤、GROUP BY分组等操作。涉及临时表时(如复杂排序),内存不足会写入磁盘。
6. 结果返回
- 格式化结果集(如 JSON 或表格),通过网络返回客户端。
三、关键优化点
- 索引优化
- 为 WHERE、JOIN、ORDER BY列添加索引,避免全表扫描。
- 提前过滤
- 在 WHERE中过滤数据,减少后续分组/排序的数据量。
- 避免 SELECT *
- 明确指定列,减少数据传输和内存占用。
- 分页优化
- 使用 WHERE id > last_id LIMIT 10替代 LIMIT 10000, 10,避免 OFFSET性能问题。
四、执行流程图示
客户端请求 → 连接管理 → 解析/预处理 → 优化器生成计划 → 存储引擎执行 → 结果返回
我将通过图文形式为你解析 select 语句的执行过程,用 4 个分镜展示关键步骤。
分镜 1:客户端发送 select 查询请求到数据库服务器,建立连接并验证权限。

分镜 2:数据库解析查询语句,生成语法树并进行语义检查,确认表和字段存在性。

分镜 3:优化器选择执行计划,通过索引扫描或全表扫描等方式获取数据。

分镜 4:执行器按计划读取数据,进行过滤排序后将结果返回客户端。





学习了