Skip to content

Commit

Permalink
planner: let the planner can select IndexMerge on MVIndex without hint (
Browse files Browse the repository at this point in the history
  • Loading branch information
qw4990 authored Jan 6, 2023
1 parent 88842fa commit 852fdc6
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 58 deletions.
18 changes: 14 additions & 4 deletions planner/core/indexmerge_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,6 @@ func (ds *DataSource) generateIndexMergeJSONMVIndexPath(normalPathCnt int, filte
if ds.possibleAccessPaths[idx].IsTablePath() || ds.possibleAccessPaths[idx].Index == nil || !ds.possibleAccessPaths[idx].Index.MVIndex {
continue // not a MVIndex path
}
if !ds.isSpecifiedInIndexMergeHints(ds.possibleAccessPaths[idx].Index.Name.L) {
continue // for safety, only consider using MVIndex when there is a `use_index_merge` hint now.
// TODO: remove this limitation
}

// Step 1. Extract the underlying JSON column from MVIndex Info.
mvIndex := ds.possibleAccessPaths[idx].Index
Expand Down Expand Up @@ -635,6 +631,20 @@ func (ds *DataSource) generateIndexMergeJSONMVIndexPath(normalPathCnt int, filte
}
indexMergePath := ds.buildIndexMergeOrPath(filters, partialPaths, filterIdx)
indexMergePath.IndexMergeIsIntersection = indexMergeIsIntersection

// Step 2.4. Update the estimated rows.
// TODO: use a naive estimation strategy here now for simplicity, make it more accurate.
minEstRows, maxEstRows := math.MaxFloat64, -1.0
for _, p := range indexMergePath.PartialIndexPaths {
minEstRows = math.Min(minEstRows, p.CountAfterAccess)
maxEstRows = math.Max(maxEstRows, p.CountAfterAccess)
}
if indexMergePath.IndexMergeIsIntersection {
indexMergePath.CountAfterAccess = minEstRows
} else {
indexMergePath.CountAfterAccess = maxEstRows
}

mvIndexPaths = append(mvIndexPaths, indexMergePath)
}
}
Expand Down
27 changes: 27 additions & 0 deletions planner/core/indexmerge_path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,30 @@ index j1((cast(j1 as signed array))))`)
result.Check(testkit.Rows(output[i].Plan...))
}
}

func TestMVIndexSelection(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, j json,
index i_int((cast(j->'$.int' as signed array))))`)

var input []string
var output []struct {
SQL string
Plan []string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)

for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
result := tk.MustQuery("explain format = 'brief' " + query)
testdata.OnRecord(func() {
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
14 changes: 14 additions & 0 deletions planner/core/testdata/index_merge_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10"
]
},
{
"name": "TestMVIndexSelection",
"cases": [
"select (j->'$.int') from t where (1 member of (j->'$.int'))",
"select * from t where (1 member of (j->'$.int'))",
"select * from t where (1 member of (j->'$.int')) and a<10",
"select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10",
"select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10"
]
},
{
"name": "TestIndexMergePathGeneration",
"cases": [
Expand Down
Loading

0 comments on commit 852fdc6

Please sign in to comment.