MYSQL--查询的执行流程
查询的执行流程
执行流程整体分为:客户端连接-连接器-查询缓存-解析器-预处理器-查询优化器-执行器-存储引擎 -返回结果。
1.连接器
建立TCP连接,校验账号密码,权限。
分配线程处理当前会话,保存该用户的表权限,视图权限。
长连接/短连接管理,空闲时超时断开。
2.查询缓存
逻辑:key=SQL文本+会话环境,value=结果集。
命中直接返回结果,跳过解析/优化/执行。
失效严重:表发生增删改,结构变更,整张表缓存全部清空,线上基本禁用
3.解析器
词法分析:拆分SQL为token(关键字,表名,字段,运算符,常量)。
语法分析:根据MySQL语法规则生成语法树AST。
4.预处理器
基于AST做语义校验:
1.检查表,字段是否存在。
2.校验别名冲突,字段歧义。
3.处理试图,存储过程,常量替换
4.权限二次校验:当前用户是否拥有该表/字段查询权限。
5.查询优化器Optimizer
输入:合法AST
输出:最优执行计划
作用:选出代价最小的执行方案
6.执行器
拿到执行计划,调用存储引擎接口逐行读取数据:
- 按计划选择索引、过滤条件、连接顺序;
- 调用引擎
read_row()获取数据; - 应用
where过滤、group by聚合、order by排序、limit截断; - 组装结果,返回客户端
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命令可查看; - 传递给执行器执行。
