优化器
BuildParseTree
libpg_query:裁剪出的
postgresql
的语法解析和词法解析。BuildParseTree
:对parser
生成的语法树进行解析,得到SelectStatement
,其中记录了语句的各个组件。1
2
3
4
5
6
7
8
9
10
11class SelectStatement : public SQLStatement {
std::unique_ptr<TableRef> from_table;
bool select_distinct;
std::vector<std::unique_ptr<expression::AbstractExpression>> select_list;
std::unique_ptr<expression::AbstractExpression> where_clause;
std::unique_ptr<GroupByDescription> group_by;
std::unique_ptr<SelectStatement> union_select;
std::unique_ptr<OrderDescription> order;
std::unique_ptr<LimitDescription> limit;
};
BindNameToNode
- 主要是用于检查
SelectStatement
中涉及的列的合法性,并将列的属性(如属于哪一张表)填入各表达式。
BuildPelotonPlanTree
Optimizer::InsertQueryTree
QueryToOperatorTransformer::ConvertToOpExpression
:将SelectStatement
转换为一棵树。树中节点如下LogicalQueryDerivedGet
:用于from
中的子查询。LogicalInnerJoin
:默认对from
中的表进行Join
,解析到from
时会生成join
树,不带条件。- 如果
from
中显示的指定了哪一类Join
,会生成对应类型的Join
,如LogicalLeftJoin
。
- 如果
LogicalGet
:递归解析from
中的元素时会解析到底层的TableRef
,生成此节点。LogicalFilter
:根据where
中的谓词生成。having子句也会生成LogicalFilter
。LogicalMarkJoin
:用于IN
和EXISTS
子链接。LogicalSingleJoin
:用于expr op sublink
,op
为比较运算符时生成。LogicalAggregateAndGroupBy
LogicalDistinct
:单独的节点,在LogicalAggregateAndGroupBy
之后生成。LogicalLimit
:在LogicalDistinct
后生成。
OptimizerMetadata::RecordTransformedExpression
:- 将上一步生成的树中的节点逐个转换为
group_expression
,每个group_expression
。- 封装层次:
Group <- GroupExpression <- Operator <- BaseOperatorNode <- <LogicalFilter...>
- 封装层次:
- 将上一步生成的树中的节点逐个转换为
Optimizer::GetQueryInfo
- 提取
output_exprs
和sort_exprs
作为后面优化的参考。
Optimizer::OptimizeLoop
通过
TaskStack
来遍历树,具体规则应用顺序:BottomUpRewrite -> TopDownRewrite -> DeriveStats -> OptimizeGroup
BottomUpRewrite
和TopDownRewrite
都是应用规则直接替换原来的节点。DeriveStats
通过栈实现
自底向上
的方式统计。主要统计以下信息:1
2
3
4
5
6size_t num_rows;
double cardinality;
double frac_null;
std::vector<double> most_common_vals,
std::vector<double> most_common_freqs;
std::vector<double> histogram_bounds;
OptimizeGroup
- 先对
LogicalExpression
通过OptimizeExpression
应用TransformationRule
和ImplementationRule
,得到多个group
,并且Expression
转换为了PhysicalExpression
。 OptimizeExpression
- 对当前
GroupExpression
添加ApplyRule
,规则为所有TransformationRule
和ImplementationRule
。 - 对当前的
child Group
调用ExploreGroup
。
- 对当前
ExploreGroup
- 对
Group
内的所有LogicalExpressions
调用ExploreExpression
。
- 对
ExploreExpression
- 对当前
GroupExpression
添加ApplyRule
,规则为所有TransformationRule
和ImplementationRule
。并且此ApplyRule
设置了explore_only
标志。 - 对当前的
child Group
调用ExploreGroup
。
- 对当前
ApplyRule
- 每次对以当前
GroupExpression
为根节点的子树应用规则。 - 通过
GroupExprBindingIterator
遍历子节点的Group
,但是每次Next()
返回都是当前GroupExpression
,只是子节点在每次调用HasNext()
时变化。 - 通过
GroupBindingIterator
遍历其中的LogicalExpression
。 - 在应用
TransformationRule
后会重新调用DeriveStats
。 - 应用规则后得到的新的子树的根节点
GroupExpression
会被放到原来的GroupExpression
所在的Group
中,其新生成的子节点都会位于不同的Group
。
- 每次对以当前
OptimizeInputs
ChildPropertyDeriver
:有的算子可能会要求前置节点的数据有序,如(PhysicalSortGroupBy
),将此种属性下推到子节点。- 选择每个
Group
中开销最小的GroupExpression
作为最佳节点,之后转换为PhysicalPlan
节点。
- 先对
优化规则
TransformationRule
InnerJoinCommutativity
+
InnerJoinAssociativity
### ImplementationRule
+
LogicalGroupByToHashGroupBy
+
LogicalAggregateToPhysical
+
GetToSeqScan
+
LogicalQueryDerivedGetToPhysical
+
InnerJoinToInnerNLJoin
+
InnerJoinToInnerHashJoin
+
ImplementDistinct
+
ImplementLimit
### RewriteRule
+
Bottom Up
:UNNEST_SUBQUERY
+
PullFilterThroughMarkJoin
PullFilterThroughAggregation
MarkJoinToInnerJoin
:即算子转换。
Top Down
:PREDICATE_PUSH_DOWN
PushFilterThroughJoin
PushFilterThroughAggregation
CombineConsecutiveFilter
EmbedFilterIntoGet
:即选择下推。
其它
visitor
模式在遍历子树时较方便。