更新时间:2026-07-28 GMT+08:00
DSL规则示例与说明
本章节内容为DSL规则匹配的示例与说明,执行结果不为实际执行结果。
规则示例场景描述
- 简要描述:两个包含Count聚集函数的表达式子链接进行等值比较时,如果其中一个子链接可以表示为另一个子链接的子结构,且过滤条件仅相差一个EXISTS子链接条件时,可以对其进行优化。因为在此场景下,实际是想找到EXISTS条件返回FALSE的情况,在这种情况下两个count值是否相等取决于其他条件是否为TRUE。当其他条件为TRUE时,根据AND条件的语义,两个子链接的过滤条件相反,count()取值一定不同;否则取值相同。因此,对于这种场景可以使用NOT EXISTS等价改写消减子链接的数量。
- SQL示例: 改写前:
SELECT t1.a, t1.b FROM table1 as t1, table2 as t2 WHERE t1.a = t2.a AND t1.b = t1.b AND ( SELECT COUNT(*) FROM table1 as t11 WHERE t11.a = t1.a AND t11.b = t1.b ) = ( SELECT COUNT(*) FROM table1 as t21 WHERE t21.a = t1.a AND t21.b = t1.b AND EXISTS( SELECT 1 FROM t3 WHERE t1.a = t3.a ) );改写后:SELECT t1.a, t1.b FROM table1 as t1, table2 as t2 WHERE t1.a = t2.a AND t1.b = t1.b AND NOT EXISTS ( SELECT 1 FROM table1 as t11 WHERE t11.a = t1.a AND t11.b = t1.b AND NOT EXISTS( SELECT 1 FROM t3 WHERE t1.a = t3.a ) );
规则示例场景DSL规则
QUERY <> {
FILTER: $exprs: * &&
(AND<>{
ARGS: $and_exp: * && ($eq_expr: OPERATOR<EQ>{
LEFT: SUBLINK<EXPRSUBLINK>{
QUERY: $ori_query: QUERY<>{
PROJECT: $proj1: AGG<COUNT>{ARGS: $agg_args1: *}
FROM: $input1: * && ($sub_l_t: (find_tables $input1 ALL))
FILTER: $FILTER1 : * && (AND<> {ARGS: $f_1 : * && (OPERATOR<EQ>{
LEFT:$f_1_l : *
RIGHT:$f_1_r : *
CONSTRAINTS: ((check_has_constraint $f_1_l UPPERVAR)
&& !(check_has_constraint $f_1_r UPPERVAR)) ||
(!(check_has_constraint $f_1_l UPPERVAR)
&& (check_has_constraint $f_1_r UPPERVAR)) &&
!(check_has_constraint THIS MODIFYCTE | VOLATILE)
})})
GROUP: GROUP<> {
GROUP: $gr1: * && ($att_list: (find_attributes $gr1 THIS))
FILTER: $h_c1: *
GROUPSET: $gr_s1: *
}
SORT: $s1 : *
}
}
RIGHT: SUBLINK<EXPRSUBLINK>{
QUERY: QUERY<>{
PROJECT: $proj2 : AGG<COUNT>{ARGS: $agg_args2: *}
FROM: $input2: * && ($sub_r_t: (find_tables $input2 ALL))
FILTER: $FILTER2 : * && (AND<> {ARGS: $f_2 : *
&& ($orther_f: SUBLINK<existssublink>{QUERY: $ssub_query: *})})
&& ($same_set : (find_expr_without $f_2 $orther_f))
GROUP: GROUP<> {
GROUP: $gr2: *
FILTER: $h_c2: *
GROUPSET: $gr_s2: *
}
SORT: $s2 : *
CONSTRAINTS: (check_is_equal $same_set $f_1)
&& (check_is_equal $gr1 $gr2)
&& (check_is_equal $h_c1 $h_c2) && (check_is_equal $gr_s1 $gr_s2)
&& (check_is_equal $s1 $s2)
&& (((check_type_foreach $proj1 COUNT_STAR)
&& (check_type_foreach $proj2 COUNT_STAR)) ||
((check_type_foreach (expr_compute $agg_args1) CONST)
&& (check_type_foreach (expr_compute $agg_args2) CONST)) ||
((check_type_foreach $agg_args1 COL)
&& (check_type_foreach $agg_args2 COL)
&& (check_is_equal $agg_args1 $agg_args2)))
&& !(check_has_constraint THIS MODIFYCTE | VOLATILE)
}
}
IGNORESIDE:true
})
}) && ($orther_expr: (find_expr_without $and_exp $eq_expr))
CONSTRAINTS: (check_has_constraint ROOT SUBLINK) &&
(check_type_foreach $exprs AND)
&& (check_type_foreach $FILTER1 AND) && (check_type_foreach $FILTER2 AND) &&
(check_is_same_table $sub_l_t $sub_r_t)
&& !(check_has_constraint ROOT MODIFYCTE | VOLATILE)
}
=>
QUERY <> {
FILTER: (append $orther_expr NOT<>{
ARGS: SUBLINK<existsSUBLINK>{
QUERY: QUERY<SELECT>{
PROJECT: CONST<INTEGER>{ARGS:1}
FROM: (build_fromexpr_by_query $ori_query $input1)
FILTER: AND <> { ARGS : (append $same_set NOT<>{
ARGS: $orther_f
})
}
GROUP: GROUP<> {
GROUP: (build_group $att_list)
FILTER: $h_c1
GROUPSET: $gr_s1
}
SORT: $s1
}
}
}
)
} 规则示例场景DSL规则详细解析
- 匹配部分:
- QUERY<>:表示匹配的是默认类型的QUERY,即SELECT类型的QUERY。
- FILTER<>:表示匹配的是约束条件。
- ARGS: $exprs: * :表示约束条件的所有内容映射到变量exprs上;&&表示进一步匹配。
- AND<> :表示仅匹配AND条件。
- ARGS: $and_exp: *:表示将匹配的AND表达式的所有内容与变量and_expr做映射。ARGS: OPERATOR<EQ>:表示匹配等值表达式。
- LEFT: SUBLINK<EXPRSUBLINK>、RIGHT: SUBLINK<EXPRSUBLINK>表示等值表达式的左右取值必须是子链接,且子链接中PROJECT: $proj1: AGG<COUNT>{}:表示投影列必须是COUNT()。
- ((check_has_constraint $f_1_l UPPERVAR) && !(check_has_constraint $f_1_r UPPERVAR)) ||
(!(check_has_constraint $f_1_l UPPERVAR) && (check_has_constraint $f_1_r UPPERVAR)):约束检查等值表达式一侧包含上层的VAR,即包含相关性条件。
- GROUP,SORT:匹配子链接中的GROUP及SORT部分。
- AND<> {ARGS: $f_2 : * && ($orther_f: SUBLINK<EXISTSSUBLINK>{QUERY: $ssub_query: *})}:对于右SUBLINK在约束里的AND条件中存在一个EXISTSSUBLINK。
- $same_set : (find_expr_without $f_2 $orther_f):表示提取$f_2中排除$orther_f的部分,映射到变量$same_set上。
- IGNORESIDE:true:表示左右两侧值可以互换进行模板匹配。
- CONSTRAINTS: (check_is_equal $same_set $f_1):表示两个子链接除右侧子链接的EXISTSSUBLINK外,其余部分都相同。
- ($orther_expr: (find_expr_without $and_exp $eq_expr)): 同样表示从约束中提取非匹配的部分。
- (((check_type_foreach $proj1 COUNT_STAR) && (check_type_foreach $proj2 COUNT_STAR)) || ((check_type_foreach (expr_compute $agg_args1) CONST) && (check_type_foreach (expr_compute $agg_args2) CONST)) || ((check_type_foreach $agg_args1 COL) && (check_type_foreach $agg_args2 COL) && (check_is_equal $agg_args1 $agg_args2))):表示左右子链接的count()函数的参数只能为count(*)、count(常量)或count相同的列。
- 改写部分:
- QUERY<>和原模板一致。
- Filter<>和原模板一致。
- ARGS:表示成员变量;append是内部函数表达将两个表达式组成链表;append $orther_expr NOT<>表示$orther_expr所映射的表达式和NOT后续表示的表达式做组合。
- ARGS: SUBLINK<EXISTSSUBLINK>: Not下是一个EXISTS子链接。
- GROUP,SORT:构建子链接的GROUP或SORT部分。
- QUERY: QUERY<SELECT> 表示子链接的QUERY成员为一个QUERY表达式。
- PROJECT: CONST<INTEGER>{ARGS:1}:表示投影列为整数1。
- FROM: (build_from_expr_from_query $ori_query $input1):表示使用函数build_from_expr_from_query构造FROM部分。
- FILTER: AND <> { ARGS : (append $same_set NOT<>:{ARGS: $orther_f}表示FILTER是AND表达式,表达式内容由append函数将$same_set所映射的表达式与$orther_f映射表达式构造NOT后进行组合。
规则示例执行结果演示
EXPLAIN (costs off)SELECT t1.C, t1.b, t2.b FROM t1, t2 WHERE t1.a = t2.a AND (SELECT COUNT(*) FROM t1 as t11 WHERE t11.a = t1.a AND t11.b = t1.b) = (SELECT COUNT(*) FROM t1 AS t21 WHERE t21.a = t1.a AND t21.b = t1.b AND EXISTS(SELECT 1 FROM t3 WHERE t1.a = t3.a));
NOTICE: Query with blockname(sel$1) is rewritten by Gs_Rewriter: SELECT t1.c, t1.b, t2.b FROM dsl_exprsublink_elimination.t1, dsl_exprsublink_elimination.t2 WHERE t1.a = t2.a AND NOT (EXISTS (SELECT 1::bigint FROM dsl_exprsublink_elimination.t1 t11 WHERE t11.a = t1.a AND t11.b = t1.b AND NOT (EXISTS (SELECT 1 AS "?column?" FROM dsl_exprsublink_elimination.t3 WHERE t1.a = t3.a)))); with rule_name sublink_compare_elimination
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Hash Join
Hash Cond: (t2.a = t1.a), (Expression Flatten Optimized)
-> Seq Scan on t2
-> Hash
-> Merge Anti Join
Merge Cond: ((t1.a = t11.a) AND (t1.b = t11.b)), (Expression Flatten Optimized)
Join Filter: (NOT (alternatives: SubPlan 1 or hashed SubPlan 2)), (Expression Flatten Optimized)
-> Sort
Sort Key: t1.a, t1.b
-> Seq Scan on t1
-> Sort
Sort Key: t11.a, t11.b
-> Seq Scan on t1 t11
SubPlan 1
-> Seq Scan on t3
Filter: (t1.a = a), (Expression Flatten Optimized)
SubPlan 2
-> Seq Scan on t3
(18 rows) 父主题: DSL规则编写规范