@@ -22,6 +22,7 @@ import (
22
22
"math"
23
23
"sort"
24
24
"strings"
25
+ "time"
25
26
26
27
"github.com/pingcap/tidb/pkg/sessionctx"
27
28
"github.com/pingcap/tidb/pkg/util/intest"
@@ -38,6 +39,8 @@ func TestKey(key string) string {
38
39
type Option struct {
39
40
MaxNumIndexes int
40
41
MaxIndexWidth int
42
+ MaxNumQuery int
43
+ Timeout time.Duration
41
44
SpecifiedSQLs []string
42
45
}
43
46
@@ -48,7 +51,12 @@ func AdviseIndexes(ctx context.Context, sctx sessionctx.Context,
48
51
return nil , errors .New ("nil input" )
49
52
}
50
53
51
- advisorLogger ().Info ("start to recommend indexes" )
54
+ advisorLogger ().Info ("fill index advisor option" )
55
+ if err := fillOption (sctx , option ); err != nil {
56
+ advisorLogger ().Error ("fill index advisor option failed" , zap .Error (err ))
57
+ return nil , err
58
+ }
59
+ advisorLogger ().Info ("index advisor option filled and start" , zap .Any ("option" , option ))
52
60
defer func () {
53
61
if r := recover (); r != nil {
54
62
advisorLogger ().Error ("panic in AdviseIndexes" , zap .Any ("recover" , r ))
@@ -61,7 +69,7 @@ func AdviseIndexes(ctx context.Context, sctx sessionctx.Context,
61
69
advisorLogger ().Info ("what-if optimizer prepared" )
62
70
63
71
defaultDB := sctx .GetSessionVars ().CurrentDB
64
- querySet , err := prepareQuerySet (ctx , sctx , defaultDB , opt , option . SpecifiedSQLs )
72
+ querySet , err := prepareQuerySet (ctx , sctx , defaultDB , opt , option )
65
73
if err != nil {
66
74
advisorLogger ().Error ("prepare workload failed" , zap .Error (err ))
67
75
return nil , err
@@ -76,7 +84,7 @@ func AdviseIndexes(ctx context.Context, sctx sessionctx.Context,
76
84
advisorLogger ().Info ("indexable columns filled" , zap .Int ("indexable-cols" , indexableColSet .Size ()))
77
85
78
86
// start the advisor
79
- indexes , err := adviseIndexes (querySet , indexableColSet , option . MaxNumIndexes , option . MaxIndexWidth , opt )
87
+ indexes , err := adviseIndexes (querySet , indexableColSet , opt , option )
80
88
if err != nil {
81
89
advisorLogger ().Error ("advise indexes failed" , zap .Error (err ))
82
90
return nil , err
@@ -94,19 +102,19 @@ func AdviseIndexes(ctx context.Context, sctx sessionctx.Context,
94
102
95
103
// prepareQuerySet prepares the target queries for the index advisor.
96
104
func prepareQuerySet (ctx context.Context , sctx sessionctx.Context ,
97
- defaultDB string , opt Optimizer , specifiedSQLs [] string ) (s.Set [Query ], error ) {
105
+ defaultDB string , opt Optimizer , option * Option ) (s.Set [Query ], error ) {
98
106
advisorLogger ().Info ("prepare target query set" )
99
107
querySet := s .NewSet [Query ]()
100
- if len (specifiedSQLs ) > 0 { // if target queries are specified
101
- for _ , sql := range specifiedSQLs {
108
+ if len (option . SpecifiedSQLs ) > 0 { // if target queries are specified
109
+ for _ , sql := range option . SpecifiedSQLs {
102
110
querySet .Add (Query {SchemaName : defaultDB , Text : sql , Frequency : 1 })
103
111
}
104
112
} else {
105
113
if intest .InTest && ctx .Value (TestKey ("query_set" )) != nil {
106
114
querySet = ctx .Value (TestKey ("query_set" )).(s.Set [Query ])
107
115
} else {
108
116
var err error
109
- if querySet , err = loadQuerySetFromStmtSummary (sctx ); err != nil {
117
+ if querySet , err = loadQuerySetFromStmtSummary (sctx , option ); err != nil {
110
118
return nil , err
111
119
}
112
120
if querySet .Size () == 0 {
@@ -117,24 +125,27 @@ func prepareQuerySet(ctx context.Context, sctx sessionctx.Context,
117
125
118
126
// filter invalid queries
119
127
var err error
120
- querySet , err = RestoreSchemaName (defaultDB , querySet , len (specifiedSQLs ) == 0 )
128
+ querySet , err = RestoreSchemaName (defaultDB , querySet , len (option . SpecifiedSQLs ) == 0 )
121
129
if err != nil {
122
130
return nil , err
123
131
}
124
- querySet , err = FilterSQLAccessingSystemTables (querySet , len (specifiedSQLs ) == 0 )
132
+ querySet , err = FilterSQLAccessingSystemTables (querySet , len (option . SpecifiedSQLs ) == 0 )
125
133
if err != nil {
126
134
return nil , err
127
135
}
128
- querySet , err = FilterInvalidQueries (opt , querySet , len (specifiedSQLs ) == 0 )
136
+ querySet , err = FilterInvalidQueries (opt , querySet , len (option . SpecifiedSQLs ) == 0 )
129
137
if err != nil {
130
138
return nil , err
131
139
}
140
+ if querySet .Size () == 0 {
141
+ return nil , errors .New ("empty query set after filtering invalid queries" )
142
+ }
132
143
advisorLogger ().Info ("finish query preparation" , zap .Int ("num_query" , querySet .Size ()))
133
144
return querySet , nil
134
145
}
135
146
136
- func loadQuerySetFromStmtSummary (sctx sessionctx.Context ) (s.Set [Query ], error ) {
137
- sql := `SELECT any_value(schema_name) as schema_name,
147
+ func loadQuerySetFromStmtSummary (sctx sessionctx.Context , option * Option ) (s.Set [Query ], error ) {
148
+ template := `SELECT any_value(schema_name) as schema_name,
138
149
any_value(query_sample_text) as query_sample_text,
139
150
sum(cast(exec_count as double)) as exec_count
140
151
FROM information_schema.statements_summary_history
@@ -144,8 +155,8 @@ func loadQuerySetFromStmtSummary(sctx sessionctx.Context) (s.Set[Query], error)
144
155
upper(schema_name) not in ("MYSQL", "INFORMATION_SCHEMA", "METRICS_SCHEMA", "PERFORMANCE_SCHEMA")
145
156
GROUP BY digest
146
157
ORDER BY sum(exec_count) DESC
147
- LIMIT 5000 `
148
- rows , err := exec (sctx , sql )
158
+ LIMIT %? `
159
+ rows , err := exec (sctx , template , option . MaxNumQuery )
149
160
if err != nil {
150
161
return nil , err
151
162
}
0 commit comments