代码位置
pkg/sql/plan.go
中的makePlan
层次结构解析
makePlan
主要是生成执行计划的作用。执行计划分为两个步骤:
1. newPlan 生成一个原始执行计划
2. optimizePlan 优化执行计划,生成最终执行计划
newPlan
会根据语句的类型生成对应的planNode。后续的说明会根据 selectCluase
解释说明。下图就是组成makePlan的代码部分。
optimizePlan
会在后续进行说明
selectCluase内部的结构
对应于selectCluase
,包含select语句的所有模块的处理操作(将AST
树转换成为执行计划树)。举例来说明:
SELECT
l.id, r.name
FROM
user l INNER JOIN profile r on l.id = r.user_id
WHERE
r.location = "beijing";
initFrom : FROM user l INNER JOIN profile r on l.id = r.user_id
initWhere : where r.location = "beijing"
initTargets : SELECT l.id, r.name
groupBy, window, orderBy, Distinct, Limit: NULL
通过initFrom
, 生成的planNode
如下图所示:
- 1 renderNode
, 代表整体的select语句
- 2 renderNode
, 代表From内部的内容
- 3 joinNode
, 代表 l join r
- 4 scan
, 代表一个表或者索引
通过 initWhere
, 重新修改 planNode
,生成的新的 planNode
如下:
1,2,3,4 代表的意思不变。
- 5 filterNode
,代表 where r.location = "beijing"
通过 initTarget
, 重新修改 planNode
,增加ResultColumns
信息,不需画图,可自行看代码。
optimizePlan内部内容
包含两个优化方向:
1. triggerFilterPropagation
filter
部分的下推等操作
2. expandPlan
selection, sort optimization
等操作
上面的语句经过triggerFilterPropagation
下推操作:
经过 expandPlan
省略,主要是通过sort
的操作进行index
的选取等。具体实例可以参考IndexMergeJoin
。