Skip to content

Commit

Permalink
planner: refine the codes of embeded limit of double read (#42818) (#…
Browse files Browse the repository at this point in the history
…43883)

ref #24636, close #35952, close #43528
  • Loading branch information
ti-chi-bot authored May 17, 2023
1 parent 73892ba commit e20734d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
11 changes: 5 additions & 6 deletions cmd/explaintest/r/explain_easy.result
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,11 @@ Projection 10000.00 root eq(test.t1.c2, test.t2.c2)->Column#11
└─Apply 10000.00 root CARTESIAN left outer join
├─TableReader(Build) 10000.00 root data:TableFullScan
│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
└─Limit(Probe) 10000.00 root offset:0, count:1
└─Projection 10000.00 root test.t2.c1, test.t2.c2
└─IndexLookUp 10000.00 root
├─Limit(Build) 10000.00 cop[tikv] offset:0, count:1
│ └─IndexRangeScan 10000.00 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo
└─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
└─Projection(Probe) 10000.00 root test.t2.c1, test.t2.c2
└─IndexLookUp 10000.00 root limit embedded(offset:0, count:1)
├─Limit(Build) 10000.00 cop[tikv] offset:0, count:1
│ └─IndexRangeScan 10000.00 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo
└─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo
explain format = 'brief' select * from t1 order by c1 desc limit 1;
id estRows task access object operator info
Limit 1.00 root offset:0, count:1
Expand Down
21 changes: 14 additions & 7 deletions planner/core/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -885,20 +885,27 @@ func (p *PhysicalLimit) sinkIntoIndexLookUp(t task) bool {
}
}

// We can sink Limit into IndexLookUpReader only if tablePlan contains no Selection.
ts, isTableScan := reader.tablePlan.(*PhysicalTableScan)
if !isTableScan {
return false
}

// If this happens, some Projection Operator must be inlined into this Limit. (issues/14428)
// For example, if the original plan is `IndexLookUp(col1, col2) -> Limit(col1, col2) -> Project(col1)`,
// then after inlining the Project, it will be `IndexLookUp(col1, col2) -> Limit(col1)` here.
// If the Limit is sunk into the IndexLookUp, the IndexLookUp's schema needs to be updated as well,
// but updating it here is not safe, so do not sink Limit into this IndexLookUp in this case now.
// So we add an extra projection to solve the problem.
if p.Schema().Len() != reader.Schema().Len() {
return false
extraProj := PhysicalProjection{
Exprs: expression.Column2Exprs(p.schema.Columns),
}.Init(p.SCtx(), p.statsInfo(), p.blockOffset, nil)
extraProj.SetSchema(p.schema)
// If the root.p is already a Projection. We left the optimization for the later Projection Elimination.
extraProj.SetChildren(root.p)
root.p = extraProj
}

// We can sink Limit into IndexLookUpReader only if tablePlan contains no Selection.
ts, isTableScan := reader.tablePlan.(*PhysicalTableScan)
if !isTableScan {
return false
}
reader.PushedLimit = &PushedDownLimit{
Offset: p.Offset,
Count: p.Count,
Expand Down
11 changes: 5 additions & 6 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@
{
"SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 order by b desc limit 2,1",
"Plan": [
"Limit 1.00 root offset:2, count:1",
"└─Projection 3.00 root test.tbl.a, test.tbl.b, test.tbl.c",
" └─IndexLookUp 3.00 root ",
" ├─Limit(Build) 3.00 cop[tikv] offset:0, count:3",
" │ └─IndexRangeScan 3.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:true, desc",
" └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tbl keep order:false"
"Projection 1.00 root test.tbl.a, test.tbl.b, test.tbl.c",
"└─IndexLookUp 1.00 root limit embedded(offset:2, count:1)",
" ├─Limit(Build) 3.00 cop[tikv] offset:0, count:3",
" │ └─IndexRangeScan 3.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:true, desc",
" └─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false"
]
},
{
Expand Down

0 comments on commit e20734d

Please sign in to comment.