Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: avoid using index_merge when there are multiple table filters (#22122) #22124

Merged
merged 4 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,12 +1185,10 @@ func (s *testIntegrationSerialSuite) TestIndexMerge(c *C) {
tk.MustQuery("show warnings").Check(testkit.Rows())

tk.MustQuery("desc select /*+ use_index_merge(t) */ * from t where (a=1 and length(b)=1) or (b=1 and length(a)=1)").Check(testkit.Rows(
"IndexMerge_9 1.60 root ",
"├─IndexRangeScan_5(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan_6(Build) 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false, stats:pseudo",
"└─Selection_8(Probe) 1.60 cop[tikv] eq(length(cast(test.t.a)), 1), eq(length(cast(test.t.b)), 1)",
" └─TableRowIDScan_7 2.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows())
"TableReader_7 8000.00 root data:Selection_6",
"└─Selection_6 8000.00 cop[tikv] or(and(eq(test.t.a, 1), eq(length(cast(test.t.b)), 1)), and(eq(test.t.b, 1), eq(length(cast(test.t.a)), 1)))",
" └─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 IndexMerge is inapplicable or disabled"))
}

func (s *testIntegrationSerialSuite) TestIssue16407(c *C) {
Expand Down Expand Up @@ -1626,3 +1624,40 @@ func (s *testIntegrationSuite) TestUpdateMultiUpdatePK(c *C) {
tk.MustExec(`UPDATE t m, t n SET m.a = m.a + 1, n.b = n.b + 10`)
tk.MustQuery("SELECT * FROM t").Check(testkit.Rows("2 12"))
}

func (s *testIntegrationSuite) TestIssue22105(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec(`CREATE TABLE t1 (
key1 int(11) NOT NULL,
key2 int(11) NOT NULL,
key3 int(11) NOT NULL,
key4 int(11) NOT NULL,
key5 int(11) DEFAULT NULL,
key6 int(11) DEFAULT NULL,
key7 int(11) NOT NULL,
key8 int(11) NOT NULL,
KEY i1 (key1),
KEY i2 (key2),
KEY i3 (key3),
KEY i4 (key4),
KEY i5 (key5),
KEY i6 (key6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`)

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(tt).Rows())
})
tk.MustQuery(tt).Check(testkit.Rows(output[i].Plan...))
}
}
11 changes: 11 additions & 0 deletions planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ func (ds *DataSource) generateIndexMergeOrPaths() {
}
if len(partialPaths) > 1 {
possiblePath := ds.buildIndexMergeOrPath(partialPaths, i)
if possiblePath == nil {
return
}

accessConds := make([]expression.Expression, 0, len(partialPaths))
for _, p := range partialPaths {
accessConds = append(accessConds, p.AccessConds...)
Expand Down Expand Up @@ -460,8 +464,15 @@ func (ds *DataSource) buildIndexMergeOrPath(partialPaths []*util.AccessPath, cur
indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths}
indexMergePath.TableFilters = append(indexMergePath.TableFilters, ds.pushedDownConds[:current]...)
indexMergePath.TableFilters = append(indexMergePath.TableFilters, ds.pushedDownConds[current+1:]...)
tableFilterCnt := 0
for _, path := range partialPaths {
// IndexMerge should not be used when the SQL is like 'select x from t WHERE (key1=1 AND key2=2) OR (key1=4 AND key3=6);'.
// Check issue https://github.com/pingcap/tidb/issues/22105 for details.
if len(path.TableFilters) > 0 {
tableFilterCnt++
if tableFilterCnt > 1 {
return nil
}
indexMergePath.TableFilters = append(indexMergePath.TableFilters, path.TableFilters...)
}
}
Expand Down
8 changes: 7 additions & 1 deletion planner/core/testdata/integration_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,11 @@
"select approx_percentile(a, 10*10) from t",
"select approx_percentile(a, 50) from t group by b order by b"
]
},
{
"name": "TestIssue22105",
"cases": [
"explain SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)"
]
}
]
]
15 changes: 15 additions & 0 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -889,5 +889,20 @@
]
}
]
},
{
"Name": "TestIssue22105",
"Cases": [
{
"SQL": "explain SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)",
"Plan": [
"StreamAgg_20 1.00 root funcs:count(Column#12)->Column#10",
"└─TableReader_21 1.00 root data:StreamAgg_9",
" └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#12",
" └─Selection_19 8000.00 cop[tikv] or(and(eq(test.t1.key4, 42), not(isnull(test.t1.key6))), and(eq(test.t1.key1, 4), eq(test.t1.key3, 6)))",
" └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
]
}
]
}
]
6 changes: 3 additions & 3 deletions planner/core/testdata/point_get_plan_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@
"Plan": [
"Point_Get_1 1.00 root table:t1, index:PRIMARY(id) "
],
"Res": []
"Res": null
},
{
"SQL": "select * from t1 where id = b'00'",
"Plan": [
"Point_Get_1 1.00 root table:t1, index:PRIMARY(id) "
],
"Res": []
"Res": null
},
{
"SQL": "select * from t1 where id = 0.0",
Expand Down Expand Up @@ -196,7 +196,7 @@
"└─IndexReader_9 10000.00 root index:IndexFullScan_8",
" └─IndexFullScan_8 10000.00 cop[tikv] table:t5, index:PRIMARY(id) keep order:false, stats:pseudo"
],
"Res": []
"Res": null
}
]
}
Expand Down