Skip to content

Commit

Permalink
planner: choose TableScan when use an empty index hint (#12037)
Browse files Browse the repository at this point in the history
  • Loading branch information
francis0407 authored and sre-bot committed Sep 6, 2019
1 parent 702854f commit d2e8bc6
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
2 changes: 1 addition & 1 deletion planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1973,7 +1973,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, nodeType n
case HintStreamAgg:
preferAggType |= preferStreamAgg
case HintIndex:
if len(hint.Tables) != 0 && len(hint.Indexes) != 0 {
if len(hint.Tables) != 0 {
indexHintList = append(indexHintList, indexHintInfo{
tblName: hint.Tables[0].TableName,
indexHint: &ast.IndexHint{
Expand Down
10 changes: 10 additions & 0 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,16 @@ type accessPath struct {
partialIndexPaths []*accessPath
}

// getTablePath finds the TablePath from a group of accessPaths.
func getTablePath(paths []*accessPath) *accessPath {
for _, path := range paths {
if path.isTablePath {
return path
}
}
return nil
}

// deriveTablePathStats will fulfill the information that the accessPath need.
// And it will check whether the primary key is covered only by point query.
func (ds *DataSource) deriveTablePathStats(path *accessPath, conds []expression.Expression) (bool, error) {
Expand Down
10 changes: 10 additions & 0 deletions planner/core/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ func (s *testPlanSuite) TestDAGPlanBuilderSimpleCase(c *C) {
sql: "select * from t t1 use index(c_d_e)",
best: "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))",
},
{
sql: "select f from t use index() where f = 1",
best: "TableReader(Table(t)->Sel([eq(test.t.f, 1)]))",
},
// Test ts + Sort vs. DoubleRead + filter.
{
sql: "select a from t where a between 1 and 2 order by c",
Expand Down Expand Up @@ -1772,6 +1776,12 @@ func (s *testPlanSuite) TestIndexHint(c *C) {
best: "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))",
hasWarn: false,
},
// use TablePath when the hint only contains table.
{
sql: "select /*+ INDEX(t) */ f from t where f > 10",
best: "TableReader(Table(t)->Sel([gt(test.t.f, 10)]))",
hasWarn: false,
},
// there will be a warning instead of error when index not exist
{
sql: "select /*+ INDEX(t, no_such_index) */ * from t",
Expand Down
11 changes: 11 additions & 0 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,17 @@ func (b *PlanBuilder) getPossibleAccessPaths(indexHints []*ast.IndexHint, tblInf
}

hasScanHint = true

// It is syntactically valid to omit index_list for USE INDEX, which means “use no indexes”.
// Omitting index_list for FORCE INDEX or IGNORE INDEX is a syntax error.
// See https://dev.mysql.com/doc/refman/8.0/en/index-hints.html.
if hint.IndexNames == nil && hint.HintType != ast.HintIgnore {
if path := getTablePath(publicPaths); path != nil {
hasUseOrForce = true
path.forced = true
available = append(available, path)
}
}
for _, idxName := range hint.IndexNames {
path := getPathByIndexName(publicPaths, idxName, tblInfo)
if path == nil {
Expand Down

0 comments on commit d2e8bc6

Please sign in to comment.