Skip to content

Commit

Permalink
planner: correctly set StatsVersion of tablePlan in copTask (#27161)
Browse files Browse the repository at this point in the history
  • Loading branch information
xuyifangreeneyes authored Aug 25, 2021
1 parent 0f459ef commit 9e248d9
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
2 changes: 1 addition & 1 deletion cmd/explaintest/r/explain_easy_stats.result
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Projection 1999.00 root eq(test.t1.c2, test.t2.c2)->Column#11
└─IndexLookUp 1.00 root
├─Limit(Build) 1.00 cop[tikv] offset:0, count:1
│ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true
└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false
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
4 changes: 4 additions & 0 deletions planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,10 @@ func (p *LogicalJoin) constructInnerIndexScanTask(
}
}
}
// We set `StatsVersion` here and fill other fields in `(*copTask).finishIndexPlan`. Since `copTask.indexPlan` may
// change before calling `(*copTask).finishIndexPlan`, we don't know the stats information of `ts` currently and on
// the other hand, it may be hard to identify `StatsVersion` of `ts` in `(*copTask).finishIndexPlan`.
ts.stats = &property.StatsInfo{StatsVersion: ds.tableStats.StatsVersion}
// If inner cop task need keep order, the extraHandleCol should be set.
if cop.keepOrder && !ds.tableInfo.IsCommonHandle {
var needExtraProj bool
Expand Down
4 changes: 4 additions & 0 deletions planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,10 @@ func (ds *DataSource) convertToIndexScan(prop *property.PhysicalProperty, candid
}.Init(ds.ctx, is.blockOffset)
ts.SetSchema(ds.schema.Clone())
ts.SetCost(cost)
// We set `StatsVersion` here and fill other fields in `(*copTask).finishIndexPlan`. Since `copTask.indexPlan` may
// change before calling `(*copTask).finishIndexPlan`, we don't know the stats information of `ts` currently and on
// the other hand, it may be hard to identify `StatsVersion` of `ts` in `(*copTask).finishIndexPlan`.
ts.stats = &property.StatsInfo{StatsVersion: ds.tableStats.StatsVersion}
cop.tablePlan = ts
}
cop.cst = cost
Expand Down
26 changes: 26 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/statistics/handle"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/testkit"
Expand Down Expand Up @@ -4217,6 +4218,31 @@ func (s *testIntegrationSuite) TestOutputSkylinePruningInfo(c *C) {
}
}

func (s *testIntegrationSuite) TestIssue27083(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int primary key, b int, c int, index idx_b(b))")
tk.MustExec("insert into t values (1,2,3), (4,5,6), (7,8,9), (10, 11, 12), (13,14,15), (16, 17, 18)")
do, _ := session.GetDomain(s.store)
c.Assert(do.StatsHandle().DumpStatsDeltaToKV(handle.DumpAll), IsNil)
tk.MustExec("analyze table t")

var input []string
var output []struct {
SQL string
Plan []string
}
s.testData.GetTestCases(c, &input, &output)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + tt).Rows())
})
tk.MustQuery("explain format = 'brief' " + tt).Check(testkit.Rows(output[i].Plan...))
}
}

func (s *testIntegrationSuite) TestIssues27130(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
10 changes: 10 additions & 0 deletions planner/core/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,12 @@ func (t *copTask) finishIndexPlan() {
var tableInfo *model.TableInfo
if t.tablePlan != nil {
ts := t.tablePlan.(*PhysicalTableScan)
originStats := ts.stats
ts.stats = t.indexPlan.statsInfo()
if originStats != nil {
// keep the original stats version
ts.stats.StatsVersion = originStats.StatsVersion
}
tableInfo = ts.Table
}
// Network cost of transferring rows of index scan to TiDB.
Expand Down Expand Up @@ -1170,7 +1175,12 @@ func (p *PhysicalLimit) sinkIntoIndexLookUp(t task) bool {
Offset: p.Offset,
Count: p.Count,
}
originStats := ts.stats
ts.stats = p.stats
if originStats != nil {
// keep the original stats version
ts.stats.StatsVersion = originStats.StatsVersion
}
reader.stats = p.stats
if isProj {
proj.stats = p.stats
Expand Down
6 changes: 6 additions & 0 deletions planner/core/testdata/integration_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -349,5 +349,11 @@
"select * from t where g = 5 order by f",
"select * from t where d = 3 order by c, e"
]
},
{
"name": "TestIssue27083",
"cases": [
"select * from t use index (idx_b) where b = 2 limit 1"
]
}
]
20 changes: 17 additions & 3 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"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:false",
"└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false, stats:pseudo"
"└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false"
]
},
{
Expand All @@ -19,7 +19,7 @@
" └─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, stats:pseudo"
" └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tbl keep order:false"
]
},
{
Expand All @@ -29,7 +29,7 @@
"├─Limit(Build) 3.00 cop[tikv] offset:0, count:3",
"│ └─Selection 3.00 cop[tikv] gt(test.tbl.c, 1)",
"│ └─IndexRangeScan 3.75 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:false",
"└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false, stats:pseudo"
"└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false"
]
},
{
Expand Down Expand Up @@ -1883,5 +1883,19 @@
]
}
]
},
{
"Name": "TestIssue27083",
"Cases": [
{
"SQL": "select * from t use index (idx_b) where b = 2 limit 1",
"Plan": [
"IndexLookUp 1.00 root limit embedded(offset:0, count:1)",
"├─Limit(Build) 1.00 cop[tikv] offset:0, count:1",
"│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:idx_b(b) range:[2,2], keep order:false",
"└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t keep order:false"
]
}
]
}
]

0 comments on commit 9e248d9

Please sign in to comment.