記錄 MySQL 查詢執行流程四大階段及優化器核心類、關鍵優化動作,基於 5.6/5.7 源碼目錄,適合內核研發與 SQL 深度調優人員。
sql_parse.cc):詞法分析 → 語法分析 → 語義檢查,生成解析樹 st_select_lex。sql_optimizer.cc → JOIN::prepare() → JOIN::optimize()):
resolve_subquery()(IN/EXISTS 轉 JOIN)、flatten_subqueries()(子查詢上拉)、simplify_joins()(外連接轉內連接)。optimize_cond()(常量折疊、等價傳遞)、opt_sum_query()(無 GROUP BY 的 COUNT/MIN/MAX 優化)。make_join_statistics()、choose_table_order()(貪心/DP 搜索最優驅動表順序)。DISTINCT、GROUP BY、ORDER BY 去重排序策略。sql_planner.cc):生成訪問路徑(JT_ALL 全表掃描、ref/range 索引掃描),實例化 QUICK_SELECT_I 及子類(Quick_range_select、Quick_index_select 等)。sql_executor.cc → JOIN::exec()):迭代器模式逐行產出結果,調用存儲引擎 Handler API。JOIN:核心控制類,繼承 Sql_alloc,包含 JOIN_TAB 數組(每表一個 join tab)、COND_EQUAL(等值傳遞鏈)、Cost_estimate(代價模型)。JOIN_TAB:單表訪問信息(table、type、ref、quick 指向 QUICK_SELECT_I)。st_select_lex:查詢塊(SELECT 詞法單元),巢狀結構對應子查詢/視圖/CTE。Key_part_spec、st_key_create_information:索引定義與鍵部分規格。COND_EQUAL:多表等值列傳遞鏈,用於 ref 訪問構建。st_position:源碼位置信息(錯誤報告用)。| 優化動作 | 入口函數/文件 |
|---|---|
| 子查詢轉 JOIN | sql_optimizer.cc → flatten_subqueries() |
| 外連接轉內連接 | sql_optimizer.cc → simplify_joins() |
| 條件化簡/常量折疊 | sql_optimizer.cc → optimize_cond() |
| 連接順序搜索 | sql_optimizer.cc → choose_table_order() |
| 索引訪問路徑構建 | sql_planner.cc → QUICK_SELECT_I 子類 |
| 無 GROUP BY 聚合優化 | sql_optimizer.cc → opt_sum_query() |
optimizer_trace(5.6+):SET optimizer_trace='enabled=on'; SELECT ...; SELECT * FROM information_schema.OPTIMIZER_TRACE; 獲取 JSON 格式優化決策細節。JOIN::optimize() 入口、choose_table_order() 循環、QUICK_SELECT_I::get_next() 索引掃描迭代器。SELECT NOW(), CURDATE(), CURTIME();