Skip to content

Sql查询的执行过程是什么

1. 总体链路:从客户端到结果集

以 MySQL 为例,一条查询从发出到返回,大致经过:

  1. 建立连接与会话(连接器/权限/参数)。
  2. SQL 解析(词法/语法)生成语法树。
  3. 预处理(语义校验、权限校验、表/列解析)。
  4. 优化器生成并选择执行计划(索引选择、JOIN 顺序、访问方法)。
  5. 执行器按计划驱动存储引擎读取数据。
  6. 结果集返回客户端(可能分批拉取)。

2. SQL 层:解析与预处理

2.1 解析(Parser)

解析阶段会把 SQL 变成内部结构(语法树),并做基础规范化处理。

2.2 预处理(Preprocess)

预处理阶段会做:

  • 表/列是否存在、类型是否匹配。
  • 权限校验。
  • 视图展开、子查询的一些改写(视优化器策略而定)。

3. 优化器:执行计划如何选择

优化器的目标是:选择“代价最低”的计划(cost-based),核心决策包括:

  • 走哪个索引(单列/联合索引、是否覆盖索引)。
  • 访问方法(全表扫、范围扫、点查、索引合并等)。
  • JOIN 顺序与 JOIN 算法(嵌套循环为主,部分场景有哈希连接等能力)。
  • 是否需要额外排序(filesort)或临时表。

计划选择强依赖统计信息(索引基数、直方图等)。统计信息不准时,可能出现“看起来应该走索引却没走”的现象。

4. 执行器与存储引擎:数据怎么被读出来

执行阶段通常表现为“迭代器模型”:执行器按照计划一步步向存储引擎取行,做过滤、投影、聚合等操作。

以 InnoDB 为例,实际读取会涉及:

  • Buffer Pool:命中则直接从内存返回,否则读取磁盘页。
  • B+ 树索引:定位记录所在页与行。
  • MVCC/锁:决定能否读到某版本、是否需要加锁(快照读/当前读)。

5. 如何验证与排查

5.1 EXPLAIN 看计划

EXPLAIN SELECT * FROM t WHERE a = 1 AND b > 10 ORDER BY c;

重点字段:

  • type:访问方式(从好到差通常是 const/ref/range/index/all)。
  • key:最终选择的索引。
  • rows:预估扫描行数。
  • Extra:是否 Using indexUsing filesortUsing temporary

5.2 结合慢日志与统计信息

执行计划不稳定或突然变慢时,通常要结合:

  • 慢查询日志(定位 SQL 与耗时)。
  • 统计信息是否过旧(触发重新分析)。
  • Buffer Pool 命中率与 I/O 压力。