From a4d48efa058643c28cc578057ca06ea158dfac07 Mon Sep 17 00:00:00 2001 From: you06 Date: Thu, 23 Dec 2021 17:16:23 +0800 Subject: [PATCH] use prop to pass expectCnt, add tests Signed-off-by: you06 --- planner/core/find_best_task.go | 1 + planner/core/plan_test.go | 24 ++++++++++++++++++++++++ planner/core/task.go | 3 ++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index 166d3adc298b3..86ee7c30db627 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -1216,6 +1216,7 @@ func (ds *DataSource) convertToIndexScan(prop *property.PhysicalProperty, candid indexPlan: is, tblColHists: ds.TblColHists, tblCols: ds.TblCols, + expectCnt: uint64(prop.ExpectedCnt), } cop.partitionInfo = PartitionInfo{ PruningConds: ds.allConds, diff --git a/planner/core/plan_test.go b/planner/core/plan_test.go index 821740a45ebe8..288444c9f2c12 100644 --- a/planner/core/plan_test.go +++ b/planner/core/plan_test.go @@ -668,6 +668,18 @@ func TestCopPaging(t *testing.T) { " └─TableRowIDScan 1024.00 cop[tikv] table:t keep order:false")) } + // selection between limit and indexlookup, limit 960 should also go paging + for i := 0; i < 10; i++ { + tk.MustQuery("explain format='brief' select * from t force index(i) where mod(id, 2) > 0 and id <= 1024 and c1 >= 0 and c1 <= 1024 and c2 in (2, 4, 6, 8) order by c1 limit 960").Check(kit.Rows( + "Limit 3.20 root offset:0, count:960", + "└─Selection 2.56 root gt(mod(test.t.id, 2), 0)", + " └─IndexLookUp 3.20 root paging:true", + " ├─Selection(Build) 819.20 cop[tikv] le(test.t.id, 1024)", + " │ └─IndexRangeScan 1024.00 cop[tikv] table:t, index:i(c1) range:[0,1024], keep order:true", + " └─Selection(Probe) 3.20 cop[tikv] in(test.t.c2, 2, 4, 6, 8)", + " └─TableRowIDScan 819.20 cop[tikv] table:t keep order:false")) + } + // limit 961 exceeds the threshold, it should not go paging for i := 0; i < 10; i++ { tk.MustQuery("explain format='brief' select * from t force index(i) where id <= 1024 and c1 >= 0 and c1 <= 1024 and c2 in (2, 4, 6, 8) order by c1 limit 961").Check(kit.Rows( @@ -678,4 +690,16 @@ func TestCopPaging(t *testing.T) { " └─Selection(Probe) 4.00 cop[tikv] in(test.t.c2, 2, 4, 6, 8)", " └─TableRowIDScan 1024.00 cop[tikv] table:t keep order:false")) } + + // selection between limit and indexlookup, limit 961 should not go paging too + for i := 0; i < 10; i++ { + tk.MustQuery("explain format='brief' select * from t force index(i) where mod(id, 2) > 0 and id <= 1024 and c1 >= 0 and c1 <= 1024 and c2 in (2, 4, 6, 8) order by c1 limit 961").Check(kit.Rows( + "Limit 3.20 root offset:0, count:961", + "└─Selection 2.56 root gt(mod(test.t.id, 2), 0)", + " └─IndexLookUp 3.20 root ", + " ├─Selection(Build) 819.20 cop[tikv] le(test.t.id, 1024)", + " │ └─IndexRangeScan 1024.00 cop[tikv] table:t, index:i(c1) range:[0,1024], keep order:true", + " └─Selection(Probe) 3.20 cop[tikv] in(test.t.c2, 2, 4, 6, 8)", + " └─TableRowIDScan 819.20 cop[tikv] table:t keep order:false")) + } } diff --git a/planner/core/task.go b/planner/core/task.go index 833ec08a4b787..1e44a18d9322e 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -925,6 +925,8 @@ func buildIndexLookUpTask(ctx sessionctx.Context, t *copTask) *rootTask { if ctx.GetSessionVars().EnablePaging && t.expectCnt > 0 && t.expectCnt <= paging.Threshold { p.Paging = true pagingCst := calcPagingCost(ctx, t) + // prevent enlarging the cost because we take paging as a better plan, + // if the cost is enlarged, it'll be easier to go another plan. idxCst = math.Min(idxCst, pagingCst) } newTask.cst += idxCst @@ -1190,7 +1192,6 @@ func (p *PhysicalLimit) attach2Task(tasks ...task) task { pushedDownLimit.SetSchema(pushedDownLimit.children[0].Schema()) pushedDownLimit.cost = cop.cost() } - cop.expectCnt = p.Count t = cop.convertToRootTask(p.ctx) sunk = p.sinkIntoIndexLookUp(t) } else if mpp, ok := t.(*mppTask); ok {