查询的执行流程

执行流程整体分为:客户端连接-连接器-查询缓存-解析器-预处理器-查询优化器-执行器-存储引擎 -返回结果。

1.连接器 

建立TCP连接,校验账号密码,权限。

分配线程处理当前会话,保存该用户的表权限,视图权限。

长连接/短连接管理,空闲时超时断开。

2.查询缓存

逻辑:key=SQL文本+会话环境,value=结果集。

命中直接返回结果,跳过解析/优化/执行。

失效严重:表发生增删改,结构变更,整张表缓存全部清空,线上基本禁用

3.解析器

词法分析:拆分SQL为token(关键字,表名,字段,运算符,常量)。

语法分析:根据MySQL语法规则生成语法树AST。

4.预处理器

基于AST做语义校验:

1.检查表,字段是否存在。

2.校验别名冲突,字段歧义。

3.处理试图,存储过程,常量替换

4.权限二次校验:当前用户是否拥有该表/字段查询权限。

5.查询优化器Optimizer

输入:合法AST

输出:最优执行计划

作用:选出代价最小的执行方案

6.执行器

拿到执行计划,调用存储引擎接口逐行读取数据:

  1. 按计划选择索引、过滤条件、连接顺序;
  2. 调用引擎read_row()获取数据;
  3. 应用where过滤、group by聚合、order by排序、limit截断;
  4. 组装结果,返回客户端

7.InnoDB存储引擎

  • 判断数据是否在缓冲池 Buffer Pool,命中直接返回;
  • 未命中走磁盘 IO 加载页到缓冲池;
  • MVCC 事务隔离、行锁、undo/redo 日志、事务可见性判断;
  • 返回行数据给执行器。

查询优化器的工作原理

MySQL优化器是基于代价的优化器CBO,核心逻辑:生成多种可执行方案,计算每种方案的预估代价,选择代价最低的执行计划。

阶段一:等价变换

不改变语义,但简化查询,减少后续计算开销。

1.常量传递:select * from t where id = 1 and a = id;

2.去除无用条件:where 1=0 直接返回空结果,and 1=1删除恒真条件

3.子查询展开/消除:IN子查询转JOIN,相关子查询扁平化,避免重复扫描。

4.外连接转内连接:若where条件过滤掉NULL,LEFT JOIN 等价于INNER JOIN ,优化连接成本

5.谓词下推:把过滤条件尽量下推到表的扫描阶段,减少JOIN行数。聚合提前过滤,having条件下推到where.

6.合并/消除派生表,视图:子查询派生表直接合并到外层,避免临时表的开销

阶段二:枚举可执行方案

优化器要做三件关键抉择,组合出大量执行方案:

1.多表JOIN连接顺序选择

2.每种表选择访问方式(单表扫描方案)

3. 排序 / 聚合策略选择

阶段三:代价模型计算Cost评估

  • 表总行数、数据页数量;
  • 索引基数(cardinality,索引区分度);
  • 单条记录长度、字段 NULL 比例;
  • 索引区间数据分布。

阶段四:生成执行计划&输出

  • 确定最终索引、JOIN 顺序、驱动表、是否 filesort、是否临时表;
  • 生成结构化执行计划,explain 命令可查看;
  • 传递给执行器执行。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐