🗣 Wd提问: MySQL源码执行计划
🤖 Ai回答: 在 MySQL 源码中,“执行计划”(Execution Plan)并不是一个独立的“源码模块”,而是指 优化器(Optimizer) 在 SQL 查询解析后,为查询生成的一个“最优执行路径”的内部表示。这个过程涉及多个源码模块协同工作。
🧩 一、什么是 MySQL 执行计划?
执行计划是 MySQL 优化器为一条 SQL 语句选择的最优访问路径和操作顺序,包括:
表的访问顺序(JOIN 顺序)
使用哪个索引(或全表扫描)
是否使用临时表、文件排序
聚合、分组、排序方式等
用户可通过 `EXPLAIN` 或 `EXPLAIN FORMAT=JSON` 查看执行计划。
📂 二、MySQL 源码中与执行计划相关的核心模块
MySQL 源码结构复杂,执行计划主要由以下部分组成:
1、解析器(Parser) → 语法树(AST)
文件:`sql/sql_yacc.yy`(Bison 语法文件)
作用:将 SQL 字符串解析为抽象语法树(Abstract Syntax Tree, AST)
例如:`SELECT * FROM t WHERE id = 1;` → 生成 `SELECT_LEX` 结构
2、优化器(Optimizer) → 生成执行计划
这是核心部分,位于:
sql/sql_optimizer.cc
sql/sql_select.cc
sql/join_optimizer/
sql/optimizer/
关键函数:
`optimize()` —— 主优化入口
`make_join_statistics()` —— 统计信息收集
`choose_plan()` —— 选择最优 JOIN 计划
`get_best_combination()` —— 枚举所有可能的 JOIN 顺序并选最优
`create_sort_index()` —— 创建排序索引(如 ORDER BY)
`test_if_skip_sort_order()` —— 判断是否可跳过排序
核心数据结构:
`JOIN`:代表整个查询的执行上下文
`JOIN_TAB`:每个表的访问方式(如 index scan, table scan)
`TABLE_REF`:索引引用信息
`ORDER` / `SORT_FIELD`:排序字段
`KEYUSE`:索引使用情况
3、执行引擎(Executor) → 执行执行计划
执行计划最终由执行器按计划执行:
文件:`sql/sql_executor.cc`, `sql/sql_select.cc`
函数:`exec_inner_select()`, `do_select()`, `evaluate_join_record()`
执行器会根据 `JOIN_TAB` 中的访问方式调用存储引擎接口(如 `handler::index_read()`)
🔄 三、执行计划生成流程(简化版)
text
SQL字符串
↓
[Parser] → 生成 AST (SELECT_LEX)
↓
[Semantic Analyzer] → 验证表/列是否存在,权限等
↓
[Optimizer] → 生成执行计划
├─ 统计信息收集(row count, key distribution)
├─ 估算各访问路径成本(Cost Model)
└─ 选择最优 JOIN 顺序和访问方法
↓
[Executor] → 按计划执行查询
↓
返回结果集
🔍 四、如何从源码调试执行计划?
1、编译调试版 MySQL
bash
cmake 、-DCMAKE_BUILD_TYPE=Debug -DWITH_DEBUG=1
make -j$(nproc)
2、设置断点观察优化器行为
gdb
(gdb) break choose_plan
(gdb) break get_best_combination
(gdb) break make_join_statistics
(gdb) run defaults-file=my.cnf
3、输出执行计划关键信息
在 `sql/sql_optimizer.cc` 中添加日志:
cpp
if (thd-variables.optimizer_trace != OPTIMIZER_TRACE_OFF) {
Opt_trace_object trace(thd-opt_trace, join_optimization);
trace.add(rows_estimation, join-rows_estimated);
}
📊 五、执行计划的数据结构示例(简化)
cpp
struct JOIN {
List<TABLE_LIST all_tables; // 所有参与查询的表
JOIN_TAB *join_tab; // 每个表的访问方式数组
uint tables; // 表数量
ha_rows send_records; // 预估返回行数
bool sort_and_group; // 是否需要排序/分组
};
struct JOIN_TAB {
TABLE *table; // 表对象
KEYUSE *keyuse; // 索引使用信息
enum join_type type; // 访问类型(eq_ref, ref, range...)
bool use_index; // 是否使用索引
ha_rows records; // 预估扫描行数
};
💡 六、扩展知识:成本模型(Cost Model)
MySQL 8.0 引入了更精细的成本模型:
基于 I/O、CPU、内存的综合成本计算
可通过 `information_schema.OPTIMIZER_COSTS` 查看默认成本参数
源码位置:`sql/opt_costconstantmanager.cc`, `sql/opt_costmodel.cc`
✅ 七、总结
| 层级 | 模块 | 功能 |
|
| 解析层 | `sql_yacc.yy` | 生成语法树 |
| 优化层 | `sql_optimizer.cc` | 生成执行计划(核心) |
| 执行层 | `sql_executor.cc` | 按计划执行查询 |
| 存储引擎 | `handler.h` | 实际访问数据 |
📘 推荐阅读源码路径
`sql/sql_optimizer.cc` —— 优化器主逻辑
`sql/sql_select.cc` —— SELECT 处理 + 执行器
`sql/join_optimizer/` —— JOIN 优化子模块
`sql/opt_costmodel.cc` —— 成本模型
`sql/sql_planner.cc` —— 执行计划构建辅助
如果你希望深入某一部分(比如 JOIN 顺序选择、索引选择算法、代价模型),可以告诉我,我可以为你展开详细讲解!
✅ 提示:想真正理解执行计划,建议结合 `EXPLAIN FORMAT=JSON` 输出 + 源码断点调试 + 注释阅读,效果最佳。
📣 商家广告:





0
IP地址: 30.52.174.204
搜索次数: 1
提问时间: 2025-11-11 07:07:48
🛒 域名购买:
68.wiki
815.red
xuesou.com.cn
59.gold
e-j.com.cn
3.hk.cn
827.net.cn
965.net.cn
n-f.cn
zansou.com.cn
❓️ 热门提问:
2011服务器cpu
电子元器件搜索引擎
ip地址中主机号全为0的是
云主机bgp
gname域名
Whois工具查域名权重
长尾关键词SEO案例
ip快速更换
工业机柜空调生产厂家
小型云主机
豌豆Ai站群搜索引擎系统
🌐 域名评估:
ez.gs
pqhn.cn
f.mo.cn
ev.ha.cn
dn.fj.cn
gbif.cn
bsiq.cn
musk.ski
bb.sx.cn
su7.bj.cn
⛏ 最新挖掘:
凯里酸汤鱼
贵阳烤脑花
都匀毛尖茶
花溪牛肉粉
贵阳烤生蚝
贵阳烤豆腐
贵阳纸包鱼
贵阳特色菜
🖌 热门作画:
🤝 关于我们:
豌豆Ai
域名
建站
站群
留痕
推广
评估
源码
开发Ai
工具
日记
价格
加盟
广告
流量
留言
联系
🗨 加入群聊:
🔗 友情链接:
香港搜尋引擎
网站优化北京
ai提问
🧰 站长工具:
Ai工具 whois查询 搜索
📢 温馨提示:本站所有问答由Ai自动创作,内容仅供参考,若有误差请用“联系”里面信息通知我们人工修改或删除。
👉 技术支持:本站由豌豆Ai提供技术支持,使用的最新版:《豌豆Ai站群搜索引擎系统 V.25.10.25》搭建本站。