Mysql 查詢執行過程 大致分為4個階段吧:
語法分析(sql_parse.cc<詞法分析, 語法分析, 語義檢查 >)
>>sql_resolver.cc # JOIN.prepare
生成邏輯查詢plan(sql_optimizer.cc)
>># JOIN.optimize
生成物理查詢plan(sql_planner.cc)
run the explain plan(sql_executor.cc) JOIN.exec
JOIN.prepare() :
子查詢的冗余子句消除
in類型子查詢優化 resolve_subquery()
將all/any等類型子查詢轉換為min/max操作 對簡單子查詢進行的優化
JOIN.optimize():
子查詢上拉 flatten_subqueries()
把外連接優化為內連接 simplify_joins()
消除嵌套連接
where子句, join/on子句,having子句化簡,含有常量的表達式化簡,等式合並 optimize_cond() opt_sum_query()
優化沒有group by 子句的下的count(*) min() man()
確定多表連接路徑 make_join_statistice()
優化distinct
創建臨時表存儲臨時結果優化分組排序 choose_table_order()
其實,邏輯與物理優化,有點混亂,分得不明確,
就是在物理查詢優化之後,繼續進行了部分邏輯優化
僅兩種單表掃描方式:
index scan(others), table scan(JT_ALL)
Opt_range.h > class QUICK_SELECT_I > 利用索引掃描滴總接口
其幾個子類 見source code;
主要的類和結構體:
查詢樹 class st_select_lex
索引 struct st_key_create_information class Key_part_spec
連接表 st_join_table
連接類 JOIN : public Sql_alloc
條件 COND_EQUAL
位置 struct st_position
代價估算 Cost_estimate
SELECT NOW(),CURDATE(),CURTIME()