Skip to content

Commit

Permalink
add new cascades optimize push topn down projection
Browse files Browse the repository at this point in the history
  • Loading branch information
hsqlu committed Dec 4, 2019
1 parent f686039 commit 5077c3d
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 13 deletions.
12 changes: 6 additions & 6 deletions planner/cascades/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@
{
"SQL": "select b from t order by b limit 3",
"Plan": [
"TopN_8 3.00 root test.t.b:asc, offset:0, count:3",
"└─Projection_10 10000.00 root test.t.b",
"Projection_8 3.00 root test.t.b",
"└─TopN_9 3.00 root test.t.b:asc, offset:0, count:3",
" └─TableReader_11 10000.00 root data:TableScan_12",
" └─TableScan_12 10000.00 cop[tikv] table:t, range:[-inf,+inf], keep order:false, stats:pseudo"
],
Expand All @@ -293,10 +293,10 @@
{
"SQL": "select a from t order by a limit 1 offset 2",
"Plan": [
"Limit_9 1.00 root offset:2, count:1",
"└─Projection_13 3.00 root test.t.a",
" └─TableReader_14 3.00 root data:TableScan_15",
" └─TableScan_15 3.00 cop[tikv] table:t, range:[-inf,+inf], keep order:true, stats:pseudo"
"Projection_8 1.00 root test.t.a",
"└─Limit_10 1.00 root offset:2, count:1",
" └─TableReader_13 3.00 root data:TableScan_14",
" └─TableScan_14 3.00 cop[tikv] table:t, range:[-inf,+inf], keep order:true, stats:pseudo"
],
"Result": [
"3"
Expand Down
4 changes: 3 additions & 1 deletion planner/cascades/testdata/transformation_rules_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"name": "TestTopNRules",
"cases": [
"select b from t order by a limit 2",
"select a+b from t order by a limit 1 offset 2"
"select a+b from t order by a limit 1 offset 2",
"select c from t order by t.a limit 1",
"select c from t order by t.a + t.b limit 1"
]
}
]
42 changes: 36 additions & 6 deletions planner/cascades/testdata/transformation_rules_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@
"Group#0 Schema:[test.t.b]",
" Projection_5 input:[Group#1], test.t.b",
"Group#1 Schema:[test.t.b,test.t.a], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#2], test.t.a:asc, offset:0, count:2",
"Group#2 Schema:[test.t.b,test.t.a], UniqueKey:[test.t.a]",
" Projection_2 input:[Group#3], test.t.b, test.t.a",
" Projection_2 input:[Group#2], test.t.b, test.t.a",
"Group#2 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#3], test.t.a:asc, offset:0, count:2",
"Group#3 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
" TableGather_7 input:[Group#4]",
"Group#4 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
Expand All @@ -219,14 +219,44 @@
"Group#0 Schema:[Column#14]",
" Projection_5 input:[Group#1], Column#13",
"Group#1 Schema:[Column#13,test.t.a], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#2], test.t.a:asc, offset:2, count:1",
"Group#2 Schema:[Column#13,test.t.a], UniqueKey:[test.t.a]",
" Projection_2 input:[Group#3], plus(test.t.a, test.t.b)->Column#13, test.t.a",
" Projection_2 input:[Group#2], plus(test.t.a, test.t.b)->Column#13, test.t.a",
"Group#2 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#3], test.t.a:asc, offset:2, count:1",
"Group#3 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
" TableGather_7 input:[Group#4]",
"Group#4 Schema:[test.t.a,test.t.b], UniqueKey:[test.t.a]",
" TableScan_6 table:t, pk col:test.t.a"
]
},
{
"SQL": "select c from t order by t.a limit 1",
"Result": [
"Group#0 Schema:[test.t.c]",
" Projection_5 input:[Group#1], test.t.c",
"Group#1 Schema:[test.t.c,test.t.a], UniqueKey:[test.t.a]",
" Projection_2 input:[Group#2], test.t.c, test.t.a",
"Group#2 Schema:[test.t.a,test.t.c], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#3], test.t.a:asc, offset:0, count:1",
"Group#3 Schema:[test.t.a,test.t.c], UniqueKey:[test.t.a]",
" TableGather_7 input:[Group#4]",
"Group#4 Schema:[test.t.a,test.t.c], UniqueKey:[test.t.a]",
" TableScan_6 table:t, pk col:test.t.a"
]
},
{
"SQL": "select c from t order by t.a + t.b limit 1",
"Result": [
"Group#0 Schema:[test.t.c]",
" Projection_5 input:[Group#1], test.t.c",
"Group#1 Schema:[test.t.c,test.t.a,test.t.b], UniqueKey:[test.t.a]",
" Projection_2 input:[Group#2], test.t.c, test.t.a, test.t.b",
"Group#2 Schema:[test.t.a,test.t.b,test.t.c], UniqueKey:[test.t.a]",
" TopN_8 input:[Group#3], plus(test.t.a, test.t.b):asc, offset:0, count:1",
"Group#3 Schema:[test.t.a,test.t.b,test.t.c], UniqueKey:[test.t.a]",
" TableGather_7 input:[Group#4]",
"Group#4 Schema:[test.t.a,test.t.b,test.t.c], UniqueKey:[test.t.a]",
" TableScan_6 table:t, pk col:test.t.a"
]
}
]
}
Expand Down
43 changes: 43 additions & 0 deletions planner/cascades/transformation_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ var defaultTransformationMap = map[memo.Operand][]Transformation{
memo.OperandLimit: {
NewRuleTransformLimitToTopN(),
},
memo.OperandTopN: {
NewRulePushTopNDownProjection(),
},
}

type baseRule struct {
Expand Down Expand Up @@ -589,3 +592,43 @@ func (r *PushSelDownJoin) OnTransform(old *memo.ExprIter) (newExprs []*memo.Grou
newJoinExpr.SetChildren(leftGroup, rightGroup)
return []*memo.GroupExpr{newJoinExpr}, true, false, nil
}

// PushTopNDownProjection pushes TopN to Projection.
type PushTopNDownProjection struct {
baseRule
}

// NewRulePushTopNDownProjection creates a new Transformation PushTopNDownProjection.
func NewRulePushTopNDownProjection() Transformation {
rule := &PushTopNDownProjection{}
rule.pattern = memo.BuildPattern(
memo.OperandTopN,
memo.EngineTiDBOnly,
memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly),
)
return rule
}

// OnTransform implements Transformation interface.
// This rule tries to pushes the TopN through Projection.
func (r *PushTopNDownProjection) OnTransform(old *memo.ExprIter) (newExprs []*memo.GroupExpr, eraseOld bool, eraseAll bool, err error) {
topN := old.GetExpr().ExprNode.(*plannercore.LogicalTopN)
proj := old.Children[0].GetExpr().ExprNode.(*plannercore.LogicalProjection)
childGroup := old.Children[0].GetExpr().Children[0]
for _, by := range topN.ByItems {
by.Expr = expression.ColumnSubstitute(by.Expr, old.Children[0].Group.Prop.Schema, proj.Exprs)
}
// remove meaningless constant sort items.
for i := len(topN.ByItems) - 1; i >= 0; i-- {
switch topN.ByItems[i].Expr.(type) {
case *expression.Constant, *expression.CorrelatedColumn:
topN.ByItems = append(topN.ByItems[:i], topN.ByItems[i+1:]...)
}
}
projExpr := memo.NewGroupExpr(proj)
topNExpr := memo.NewGroupExpr(topN)
topNExpr.SetChildren(childGroup)
topNGroup := memo.NewGroupWithSchema(topNExpr, childGroup.Prop.Schema)
projExpr.SetChildren(topNGroup)
return []*memo.GroupExpr{projExpr}, true, false, nil
}
3 changes: 3 additions & 0 deletions planner/cascades/transformation_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ func (s *testTransformationRuleSuite) TestTopNRules(c *C) {
memo.OperandDataSource: {
NewRuleEnumeratePaths(),
},
memo.OperandTopN: {
NewRulePushTopNDownProjection(),
},
})
var input []string
var output []struct {
Expand Down

0 comments on commit 5077c3d

Please sign in to comment.