MySQL Server 源码剖析 - SQL核心层-API详解
一、模块概述
SQL 核心层是 MySQL Server 处理 SQL 语句的核心组件,包含解析器(Parser)、优化器(Optimizer)、执行器(Executor)三大子模块。本文档深入分析每个模块的核心 API、数据结构、调用链路和时序图。
二、核心 API 入口函数
2.1 主要 API 入口点
flowchart TB
CLIENT[客户端请求] --> DISPATCH[dispatch_command]
DISPATCH --> DISPATCH_SQL[dispatch_sql_command]
DISPATCH_SQL --> PARSE[parse_sql]
DISPATCH_SQL --> OPTIMIZE[JOIN::optimize]
DISPATCH_SQL --> EXECUTE[Query_expression::execute]
PARSE --> LEXER[词法分析器]
PARSE --> PARSER[语法分析器]
OPTIMIZE --> CBO[基于成本的优化]
OPTIMIZE --> REWRITE[查询重写]
EXECUTE --> ITERATOR[迭代器执行]
EXECUTE --> RESULT[结果返回]
style DISPATCH fill:#fff4e1
style PARSE fill:#e8f5e9
style OPTIMIZE fill:#f3e5f5
style EXECUTE fill:#e1f5ff
三、解析器模块 API 详解
3.1 核心入口函数:dispatch_sql_command
函数签名:
void dispatch_sql_command(THD *thd, Parser_state *parser_state, bool is_retry);
功能说明:
- 分发 SQL 命令处理的主入口点
- 负责初始化解析状态、调用解析器、处理解析结果
- 支持多语句处理和查询重写
核心代码:
void dispatch_sql_command(THD *thd, Parser_state *parser_state, bool is_retry) {
// 1. 重置 THD 状态,准备处理新命令
mysql_reset_thd_for_next_command(thd);
thd->reset_rewritten_query();
lex_start(thd);
// 2. 设置解析状态和预处理插件
thd->m_parser_state = parser_state;
invoke_pre_parse_rewrite_plugins(thd);
thd->m_parser_state = nullptr;
// 3. 启用查询摘要计算
if (get_max_digest_length() != 0)
parser_state->m_input.m_compute_digest = true;
LEX *lex = thd->lex;
const char *found_semicolon = nullptr;
bool err = thd->get_stmt_da()->is_error();
// 4. 核心解析过程
if (!err) {
err = parse_sql(thd, parser_state, nullptr);
if (!err) err = invoke_post_parse_rewrite_plugins(thd, false);
found_semicolon = parser_state->m_lip.found_semicolon;
// (此处省略多语句处理逻辑)
}
// 5. 查询重写和日志记录
// (此处省略查询重写逻辑)
// 6. 执行具体的 SQL 命令
if (!err) {
err = mysql_execute_command(thd, true);
// (此处省略错误处理和清理逻辑)
}
}
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
thd |
THD * |
线程描述符,包含连接状态和会话信息 |
parser_state |
Parser_state * |
解析器状态,包含 SQL 文本和位置信息 |
is_retry |
bool |
是否为重试请求(用于错误恢复) |
返回值:无(通过 thd->get_stmt_da() 返回错误状态)
3.2 核心解析函数:parse_sql
函数签名:
bool parse_sql(THD *thd, Parser_state *parser_state, Object_creation_ctx *creation_ctx);
功能说明:
- SQL 解析的核心函数
- 将 SQL 文本转换为抽象语法树(AST)
- 支持查询摘要生成和错误恢复
核心代码:
bool parse_sql(THD *thd, Parser_state *parser_state, Object_creation_ctx *creation_ctx) {
DBUG_TRACE;
// 1. 保存当前状态
Object_creation_ctx *backup_ctx = nullptr;
if (creation_ctx) {
backup_ctx = thd->restore_object_creation_ctx(creation_ctx);
}
// 2. 设置解析器状态
thd->m_parser_state = parser_state;
thd->reset_n_backup_open_tables_state(&open_tables_state_backup,
MYSQL_OPEN_REOPEN_POLICY::CLOSE_SYSTEM_TABLES);
// 3. 调用 YACC 生成的解析器
bool ret_value = thd->sql_parser();
// 4. 恢复状态和错误处理
if (ret_value && !thd->is_error()) {
// 解析失败但未设置错误,生成语法错误
const char *error_msg = parser_state->m_lip.error_msg;
if (!error_msg) error_msg = ER_DEFAULT(ER_SYNTAX_ERROR);
my_error(ER_PARSE_ERROR, MYF(0), error_msg,
parser_state->m_lip.yytext,
parser_state->m_lip.yylineno);
}
// 5. 清理和恢复
thd->end_statement();
thd->m_parser_state = nullptr;
thd->restore_backup_open_tables_state(&open_tables_state_backup);
if (creation_ctx) {
thd->restore_object_creation_ctx(backup_ctx);
}
return ret_value;
}
调用链路分析:
sequenceDiagram
autonumber
participant CLIENT as 客户端
participant DISPATCH as dispatch_command
participant DISPATCH_SQL as dispatch_sql_command
participant PARSE_SQL as parse_sql
participant SQL_PARSER as THD::sql_parser
participant YACC as my_sql_parser_parse
CLIENT->>DISPATCH: COM_QUERY 命令
DISPATCH->>DISPATCH_SQL: 调用 SQL 命令分发
DISPATCH_SQL->>DISPATCH_SQL: 初始化解析状态
DISPATCH_SQL->>PARSE_SQL: 调用解析函数
PARSE_SQL->>SQL_PARSER: 调用 THD 解析器
SQL_PARSER->>YACC: 调用 YACC 生成的解析器
YACC-->>SQL_PARSER: 返回解析结果(AST)
SQL_PARSER-->>PARSE_SQL: 返回解析状态
PARSE_SQL-->>DISPATCH_SQL: 返回解析结果
DISPATCH_SQL->>DISPATCH_SQL: 执行 SQL 命令
3.3 解析器状态结构:Parser_state
数据结构:
struct Parser_state {
// 输入状态
struct {
const char *m_ptr; // 当前解析位置
const char *m_end; // SQL 文本结束位置
bool m_compute_digest; // 是否计算查询摘要
bool m_has_digest; // 是否已有摘要
} m_input;
// 词法分析器状态
Lex_input_stream m_lip; // 词法分析器
// 解析器状态
bool init(THD *thd, const char *buff, unsigned int length);
void reset(const char *found_semicolon, unsigned int length);
};
字段功能说明:
| 字段 | 类型 | 功能说明 |
|---|---|---|
m_input.m_ptr |
const char * |
当前解析位置指针 |
m_input.m_end |
const char * |
SQL 文本结束位置 |
m_input.m_compute_digest |
bool |
是否计算 SQL 摘要(用于 Performance Schema) |
m_lip |
Lex_input_stream |
词法分析器,负责词法单元识别 |
3.4 词法分析器:Lex_input_stream
核心功能:
- 将 SQL 文本分解为词法单元(Token)
- 处理注释、字符串字面量、标识符
- 支持多种字符集和大小写敏感性
关键方法:
class Lex_input_stream {
public:
// 获取下一个词法单元
int lex_one_token(union YYSTYPE *yylval, THD *thd);
// 跳过空白字符和注释
void skip_white();
// 处理字符串字面量
int scan_string(THD *thd, char quote_char);
// 处理数字字面量
int scan_number(THD *thd, char first_char);
// 处理标识符
int scan_identifier(THD *thd);
private:
const char *m_ptr; // 当前位置
const char *m_end_of_query; // 查询结束位置
uint yylineno; // 当前行号
const char *yytext; // 当前词法单元文本
const char *found_semicolon; // 找到的分号位置
};
四、优化器模块 API 详解
4.1 核心入口函数:JOIN::optimize
函数签名:
bool JOIN::optimize(bool finalize_access_paths);
功能说明:
- 查询优化的主入口点
- 执行逻辑变换、基于成本的优化、后连接优化
- 生成最优的查询执行计划
核心代码:
bool JOIN::optimize(bool finalize_access_paths) {
DBUG_TRACE;
// 1. 逻辑变换阶段
if (prepare_stage()) return true;
// 外连接到内连接转换
if (simplify_joins(this, join_list, true, false, &conds, true))
return true;
// 常量传播和分区裁剪
if (propagate_constants()) return true;
// 2. 基于成本的连接优化
if (Optimize_table_order(thd, this, nullptr).choose_table_order())
return true;
// 3. 后连接优化阶段
if (make_join_statistics(this, tables_list, &conds))
return true;
// 创建最优的表条件
if (optimize_cond(thd, &conds, &cond_equal, join_list,
&select_lex->where_cond()))
return true;
// 注入外连接保护条件
if (build_equal_items(this, conds, nullptr, false, join_list, &cond_equal))
return true;
// 4. 代码生成阶段
if (finalize_access_paths) {
if (create_iterators()) return true;
}
return false;
}
优化阶段详解:
4.1.1 逻辑变换阶段
外连接到内连接转换:
bool simplify_joins(JOIN *join, List<Table_ref> *join_list,
bool top, bool in_sj, Item **new_conds, bool is_explain) {
// 分析 WHERE 条件,识别可以将外连接转换为内连接的情况
for (Table_ref *table : *join_list) {
if (table->outer_join) {
// 检查 WHERE 条件是否引用了外连接的内表
if (can_convert_outer_to_inner_join(table, *new_conds)) {
table->outer_join = 0; // 转换为内连接
// (此处省略统计信息更新)
}
}
}
return false;
}
常量传播:
bool JOIN::propagate_constants() {
// 查找等式条件 (col = const)
for (Item_equal *item_equal : cond_equal.current_level) {
if (item_equal->const_item()) {
Item *constant = item_equal->get_const();
// 将常量传播到所有相等的列
for (Item_field *field : item_equal->fields) {
substitute_for_best_equal_field(field, constant);
}
}
}
return false;
}
4.1.2 基于成本的优化
表连接顺序优化:
class Optimize_table_order {
public:
bool choose_table_order() {
// 1. 初始化成本计算
if (init_cost_calculation()) return true;
// 2. 搜索最优连接顺序
if (search_best_join_order()) return true;
// 3. 应用最优顺序
if (apply_best_join_order()) return true;
return false;
}
private:
// 动态规划搜索最优连接顺序
bool search_best_join_order() {
// 对于每个表子集,计算最优的连接方案
for (table_map tables_in_plan = 1;
tables_in_plan < (1ULL << table_count);
tables_in_plan++) {
Position best_pos;
double best_cost = DBL_MAX;
// 尝试每个可能的下一个表
for (uint idx = 0; idx < table_count; idx++) {
if (!(tables_in_plan & (1ULL << idx))) continue;
Position pos;
// 计算添加该表的成本
double cost = calculate_join_cost(tables_in_plan, idx, &pos);
if (cost < best_cost) {
best_cost = cost;
best_pos = pos;
}
}
// 保存最优方案
save_best_plan(tables_in_plan, best_pos, best_cost);
}
return false;
}
};
4.2 新优化器:FindBestQueryPlan
函数签名:
AccessPath *FindBestQueryPlan(THD *thd, Query_block *query_block);
功能说明:
- MySQL 8.0 引入的超图连接优化器
- 基于超图表示的连接关系
- 支持更复杂的连接模式和更精确的成本计算
核心代码:
AccessPath *FindBestQueryPlan(THD *thd, Query_block *query_block) {
bool retry = false;
int subgraph_pair_limit = 100000;
do {
AccessPath *path = FindBestQueryPlanInner(thd, query_block,
&retry, &subgraph_pair_limit);
if (!retry) return path;
// 如果子图对数量过多,减少限制并重试
subgraph_pair_limit /= 2;
} while (retry && subgraph_pair_limit >= 1000);
return nullptr;
}
static AccessPath *FindBestQueryPlanInner(THD *thd, Query_block *query_block,
bool *retry, int *subgraph_pair_limit) {
JOIN *join = query_block->join;
// 1. 构建连接超图
JoinHypergraph graph(thd->mem_root);
if (MakeJoinHypergraph(thd, &graph)) return nullptr;
// 2. 枚举所有合法的子图连接
Mem_root_array<AccessPath *> access_paths(thd->mem_root);
if (EnumerateAllConnectedPartitions(graph, &access_paths,
*subgraph_pair_limit, retry))
return nullptr;
// 3. 选择成本最低的访问路径
AccessPath *best_path = nullptr;
double best_cost = DBL_MAX;
for (AccessPath *path : access_paths) {
double cost = path->cost;
if (cost < best_cost) {
best_cost = cost;
best_path = path;
}
}
// 4. 添加后处理操作(GROUP BY、ORDER BY 等)
if (best_path) {
best_path = AddPostProcessingOperations(thd, best_path);
}
return best_path;
}
4.3 成本计算模型
成本结构:
struct Cost_estimate {
double io_cost; // I/O 成本
double cpu_cost; // CPU 成本
double mem_cost; // 内存成本
double import_cost; // 导入成本(用于物化)
// 总成本计算
double total_cost() const {
return io_cost + cpu_cost + mem_cost + import_cost;
}
};
表访问成本计算:
double calculate_table_scan_cost(const Table_ref *table) {
const TABLE *tab = table->table;
// 全表扫描成本 = 页数 * I/O 成本 + 行数 * CPU 成本
double io_cost = tab->file->scan_time() * server_cost_constants.io_block_read_cost;
double cpu_cost = tab->file->records() * server_cost_constants.row_eval_cost;
return io_cost + cpu_cost;
}
double calculate_index_scan_cost(const Table_ref *table, uint key_no,
ha_rows rows_to_read) {
const TABLE *tab = table->table;
// 索引扫描成本 = 索引页数 * I/O 成本 + 读取行数 * CPU 成本
double io_cost = tab->file->read_time(key_no, 1, rows_to_read) *
server_cost_constants.io_block_read_cost;
double cpu_cost = rows_to_read * server_cost_constants.row_eval_cost;
return io_cost + cpu_cost;
}
五、执行器模块 API 详解
5.1 核心入口函数:Query_expression::execute
函数签名:
bool Query_expression::execute(THD *thd);
功能说明:
- 查询执行的主入口点
- 协调多个查询块的执行(UNION 处理)
- 管理结果集的产生和传输
核心代码:
bool Query_expression::execute(THD *thd) {
DBUG_TRACE;
// 1. 检查是否已优化
assert(is_optimized());
// 2. 执行准备工作
if (prepare_execution(thd)) return true;
// 3. 分情况执行
if (is_simple()) {
// 单一查询块执行
return first_query_block()->join->exec();
} else {
// UNION 查询执行
return execute_union(thd);
}
}
bool Query_expression::execute_union(THD *thd) {
// 1. 创建临时表存储 UNION 结果
if (create_result_table()) return true;
// 2. 执行每个查询块
for (Query_block *query_block = first_query_block();
query_block != nullptr;
query_block = query_block->next_query_block()) {
if (query_block->join->exec()) return true;
// 3. 将结果写入临时表
if (write_to_union_table(query_block)) return true;
}
// 4. 处理 UNION 后的操作(ORDER BY、LIMIT)
if (process_union_result()) return true;
return false;
}
5.2 连接执行:JOIN::exec
函数签名:
bool JOIN::exec();
功能说明:
- 单个查询块的执行入口
- 管理表的扫描和连接操作
- 处理 GROUP BY、ORDER BY、HAVING 等操作
核心代码:
bool JOIN::exec() {
DBUG_TRACE;
// 1. 检查优化状态
assert(optimized);
// 2. 准备执行环境
if (setup_execution()) return true;
// 3. 创建迭代器执行引擎
if (create_iterators()) return true;
// 4. 执行查询
if (m_root_iterator->Init()) return true;
POS_ROW_COUNT row_count = 0;
while (true) {
int result = m_root_iterator->Read();
if (result == 1) return true; // 错误
if (result == -1) break; // 结束
// 5. 发送结果行到客户端
if (send_result_row()) return true;
row_count++;
// 6. 检查 LIMIT
if (unit->offset_limit_cnt && row_count >= unit->offset_limit_cnt)
break;
}
return false;
}
5.3 迭代器执行引擎
MySQL 8.0 引入了基于迭代器的执行引擎,每种操作对应一个迭代器类:
迭代器基类:
class RowIterator {
public:
virtual ~RowIterator() = default;
// 初始化迭代器
virtual bool Init() = 0;
// 读取下一行,返回值:
// 0: 成功读取到行
// -1: 无更多行(EOF)
// 1: 错误
virtual int Read() = 0;
// 获取当前行数据(存储在 table->record[0] 中)
virtual void UnlockRow() {}
// 迭代器类型(用于 EXPLAIN)
virtual IteratorType type() const = 0;
// 成本信息
virtual double cost() const { return 0.0; }
virtual ha_rows num_output_rows() const { return 0; }
};
表扫描迭代器:
class TableScanIterator : public RowIterator {
public:
TableScanIterator(THD *thd, TABLE *table)
: m_thd(thd), m_table(table) {}
bool Init() override {
return m_table->file->ha_rnd_init(true); // 初始化全表扫描
}
int Read() override {
int result = m_table->file->ha_rnd_next(m_table->record[0]);
if (result == 0) {
// 成功读取行,检查 WHERE 条件
if (m_condition && !m_condition->val_int()) {
return Read(); // 递归读取下一行
}
return 0;
} else if (result == HA_ERR_END_OF_FILE) {
return -1; // 结束
} else {
return 1; // 错误
}
}
private:
THD *m_thd;
TABLE *m_table;
Item *m_condition; // WHERE 条件
};
嵌套循环连接迭代器:
class NestedLoopJoinIterator : public RowIterator {
public:
NestedLoopJoinIterator(unique_ptr<RowIterator> outer,
unique_ptr<RowIterator> inner,
Item *join_condition)
: m_outer_iterator(move(outer)),
m_inner_iterator(move(inner)),
m_join_condition(join_condition) {}
bool Init() override {
if (m_outer_iterator->Init()) return true;
m_outer_eof = false;
m_reading_first_inner_row = true;
return false;
}
int Read() override {
for (;;) {
if (m_reading_first_inner_row) {
// 读取外表的下一行
int result = m_outer_iterator->Read();
if (result != 0) return result;
// 初始化内表扫描
if (m_inner_iterator->Init()) return 1;
m_reading_first_inner_row = false;
}
// 读取内表的下一行
int result = m_inner_iterator->Read();
if (result == 0) {
// 检查连接条件
if (m_join_condition == nullptr || m_join_condition->val_int()) {
return 0; // 连接成功
}
// 连接条件不满足,继续读取内表
continue;
} else if (result == -1) {
// 内表结束,读取外表下一行
m_reading_first_inner_row = true;
continue;
} else {
return 1; // 错误
}
}
}
private:
unique_ptr<RowIterator> m_outer_iterator;
unique_ptr<RowIterator> m_inner_iterator;
Item *m_join_condition;
bool m_outer_eof;
bool m_reading_first_inner_row;
};
六、关键数据结构详解
6.1 THD(Thread Descriptor)
结构概述:
class THD : public MDL_context, public Query_arena, public Open_tables_state {
public:
// 连接信息
Security_context m_main_security_ctx; // 安全上下文
NET net; // 网络连接
String packet; // 数据包缓冲区
// SQL 相关
LEX *lex; // 当前 SQL 的词法分析结果
Query_arena *stmt_arena; // 内存分配器
// 事务相关
struct Transaction_state {
Ha_trx_info *ha_list; // 存储引擎事务列表
bool no_2pc; // 是否禁用两阶段提交
} transaction;
// 状态标志
bool killed; // 是否被杀死
bool is_error() const; // 是否有错误
// 查询处理
bool sql_parser(); // SQL 解析入口
void reset_for_next_command(); // 重置状态准备下一个命令
};
关键字段说明:
| 字段 | 类型 | 功能说明 |
|---|---|---|
lex |
LEX * |
词法分析结果,包含解析后的 SQL 结构 |
net |
NET |
网络连接信息,用于与客户端通信 |
transaction |
Transaction_state |
事务状态信息 |
killed |
bool |
线程是否被请求终止 |
6.2 LEX(Lexical Analysis)
结构概述:
struct LEX : public Query_tables_list {
// SQL 命令类型
enum_sql_command sql_command;
// 查询结构
Query_expression *unit; // 查询表达式(支持 UNION)
Query_block *query_block; // 当前查询块
// 解析状态
sp_head *sphead; // 存储过程头
enum_lex_state context_analysis_only; // 上下文分析模式
// 表和列信息
Table_ref *query_tables; // 查询涉及的表
List<Item> item_list; // SELECT 列表
Item *where; // WHERE 条件
// 其他子句
SQL_I_List<ORDER> order_list; // ORDER BY 子句
Item *having; // HAVING 条件
ha_rows limit_rows_examined; // LIMIT 行数
// 方法
bool make_sql_cmd(Parse_tree_root *parse_tree); // 创建 SQL 命令对象
};
6.3 JOIN(连接执行计划)
结构概述:
class JOIN {
public:
THD *thd; // 线程描述符
Query_block *query_block; // 所属查询块
// 表信息
uint table_count; // 表数量
Table_ref **best_ref; // 最优表顺序
JOIN_TAB *join_tab; // 连接表数组
// 优化信息
bool optimized; // 是否已优化
Item *conds; // WHERE 条件
COND_EQUAL cond_equal; // 等式条件
// 执行器
unique_ptr<RowIterator> m_root_iterator; // 根迭代器
// 方法
bool optimize(bool finalize_access_paths); // 优化
bool exec(); // 执行
bool create_iterators(); // 创建迭代器
};
七、API 调用链路时序图
7.1 完整 SQL 处理时序图
sequenceDiagram
autonumber
participant C as 客户端
participant D as dispatch_command
participant DS as dispatch_sql_command
participant P as parse_sql
participant L as sql_parser (YACC)
participant O as JOIN::optimize
participant E as JOIN::exec
participant I as RowIterator
participant S as 存储引擎
C->>D: COM_QUERY 请求
D->>D: 检查连接状态
D->>DS: 分发 SQL 命令
Note over DS: 解析阶段
DS->>DS: 初始化解析状态
DS->>P: 调用解析函数
P->>L: 调用 YACC 解析器
L->>L: 词法分析(Tokenization)
L->>L: 语法分析(AST 构建)
L-->>P: 返回 AST
P-->>DS: 返回解析结果
Note over DS: 优化阶段
DS->>O: 调用查询优化
O->>O: 逻辑变换(外连接转内连接)
O->>O: 常量传播
O->>O: 分区裁剪
O->>O: 基于成本的表顺序优化
O->>O: 访问路径选择
O->>O: 创建执行迭代器
O-->>DS: 返回优化结果
Note over DS: 执行阶段
DS->>E: 调用查询执行
E->>I: 初始化根迭代器
loop 读取结果行
I->>S: 调用存储引擎读取
S-->>I: 返回行数据
I->>I: 应用过滤条件
I->>I: 执行连接操作
I-->>E: 返回结果行
E->>C: 发送行数据到客户端
end
E-->>DS: 执行完成
DS-->>D: 命令完成
D-->>C: 发送 OK 包
7.2 查询优化详细时序图
sequenceDiagram
autonumber
participant O as JOIN::optimize
participant P as prepare_stage
participant S as simplify_joins
participant C as propagate_constants
participant T as Optimize_table_order
participant M as make_join_statistics
participant OC as optimize_cond
participant CI as create_iterators
O->>P: 准备优化阶段
P->>P: 初始化统计信息
P->>P: 解析 WHERE 条件
P-->>O: 准备完成
O->>S: 简化连接
S->>S: 分析外连接条件
S->>S: 转换外连接为内连接
S-->>O: 连接简化完成
O->>C: 常量传播
C->>C: 查找等式条件
C->>C: 替换常量表达式
C-->>O: 常量传播完成
O->>T: 优化表连接顺序
T->>T: 计算表访问成本
loop 动态规划搜索
T->>T: 枚举表子集
T->>T: 计算连接成本
T->>T: 保存最优方案
end
T-->>O: 最优顺序确定
O->>M: 生成连接统计
M->>M: 计算选择性
M->>M: 估算结果行数
M-->>O: 统计完成
O->>OC: 优化条件表达式
OC->>OC: 下推条件到表
OC->>OC: 创建索引条件
OC-->>O: 条件优化完成
O->>CI: 创建执行迭代器
CI->>CI: 构建迭代器树
CI->>CI: 设置过滤条件
CI-->>O: 迭代器创建完成
八、性能监控与调试
8.1 关键性能指标
-- 查看 SQL 解析统计
SHOW STATUS LIKE 'Com_select%';
SHOW STATUS LIKE 'Com_insert%';
SHOW STATUS LIKE 'Com_update%';
SHOW STATUS LIKE 'Com_delete%';
-- 查看查询缓存统计(MySQL 5.7 及之前)
SHOW STATUS LIKE 'Qcache%';
-- 查看临时表使用
SHOW STATUS LIKE 'Created_tmp%';
-- 查看排序操作
SHOW STATUS LIKE 'Sort%';
8.2 优化器跟踪
-- 启用优化器跟踪
SET optimizer_trace="enabled=on";
-- 执行查询
SELECT * FROM users u JOIN orders o ON u.id = o.user_id WHERE u.status = 'active';
-- 查看优化过程
SELECT TRACE FROM information_schema.OPTIMIZER_TRACE;
8.3 执行计划分析
-- 查看执行计划
EXPLAIN FORMAT=TREE
SELECT * FROM users u JOIN orders o ON u.id = o.user_id WHERE u.status = 'active';
-- 查看详细执行统计
EXPLAIN ANALYZE
SELECT * FROM users u JOIN orders o ON u.id = o.user_id WHERE u.status = 'active';
九、总结
SQL 核心层的 API 体系包含三个主要模块:
解析器模块:
dispatch_sql_command:SQL 命令分发入口parse_sql:核心解析函数THD::sql_parser:YACC 解析器调用- 支持多语句、查询重写、错误恢复
优化器模块:
JOIN::optimize:传统优化器(基于动态规划)FindBestQueryPlan:新优化器(基于超图)- 包含逻辑变换、成本优化、代码生成三个阶段
- 支持复杂的连接优化和访问路径选择
执行器模块:
Query_expression::execute:查询执行入口JOIN::exec:连接执行- 基于迭代器的执行引擎(MySQL 8.0+)
- 支持向量化处理和延迟物化
每个模块都有清晰的 API 边界和数据结构,通过统一的调用链路协同工作,为上层提供完整的 SQL 处理能力。