Skip to content

Commit 48f6c86

Browse files
authored
Merge pull request pingcap#5 from IggieWang/newidxadv
new framework
2 parents d9ae3a2 + 18f02a3 commit 48f6c86

File tree

6 files changed

+279
-237
lines changed

6 files changed

+279
-237
lines changed

idxadvisor/idxadvisor.go

Lines changed: 52 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type idxAdvPool []*IdxAdvisor
2121
const queryChanSize int = 10000
2222

2323
var registeredIdxAdv = make(map[uint64]*IdxAdvisor)
24+
2425
var idxadvPool idxAdvPool = make(idxAdvPool, 0)
2526

2627
func (iap *idxAdvPool) push(ia *IdxAdvisor) {
@@ -65,8 +66,6 @@ func (ci CandidateIdxes) Less(i, j int) bool { return ci[i].Benefit > ci[j].Bene
6566
func (ci CandidateIdxes) Swap(i, j int) { ci[i], ci[j] = ci[j], ci[i] }
6667

6768
// NewIdxAdv create a new IdxAdvisor.
68-
// TODO: *sql.DB is not supposed to a member of IdxAdvisor.
69-
// *sql.DB can interacts with idxadvisor by session variable
7069
func NewIdxAdv(db *sql.DB) *IdxAdvisor {
7170
ia := &IdxAdvisor{dbClient: db}
7271
ia.ready.Store(false)
@@ -75,14 +74,15 @@ func NewIdxAdv(db *sql.DB) *IdxAdvisor {
7574
return ia
7675
}
7776

78-
// MockNewIdxAdv() return *IdxAdvisor without initiating dbClient member
77+
// MockNewIdxAdv return *IdxAdvisor without initiating dbClient member
7978
func MockNewIdxAdv() *IdxAdvisor {
8079
ia := &IdxAdvisor{}
8180
ia.ready.Store(false)
8281
idxadvPool.push(ia)
8382
return ia
8483
}
8584

85+
// GetIdxAdv returns a IdxAdvisor according to connID.
8686
func GetIdxAdv(connID uint64) *IdxAdvisor {
8787
if ia, ok := registeredIdxAdv[connID]; ok {
8888
return ia
@@ -96,45 +96,6 @@ func GetIdxAdv(connID uint64) *IdxAdvisor {
9696
}
9797
}
9898

99-
//// GetRecommendIdx return recommend index within given connection
100-
//func GetRecommendIdx(connID uint64) (*CandidateIdxes, error) {
101-
// if ia, ok := registeredIdxAdv[connID]; !ok {
102-
// return nil, errors.New(fmt.Sprintf(
103-
// "bad attempt to get recommend index with no registered index advisor. connID: %v\n", connID))
104-
// } else {
105-
// return &ia.Candidate_idx, nil
106-
// }
107-
//}
108-
109-
// GetRecommendIdxStr return recommend index in string format. Used in test
110-
func GetRecommendIdxStr(connID uint64) (string, error) {
111-
if ia, ok := registeredIdxAdv[connID]; !ok {
112-
return "", errors.New(fmt.Sprintf(
113-
"bad attempt to get recommend index with no registered index advisor. connID: %v\n", connID))
114-
} else {
115-
idxes := ia.Candidate_idx
116-
if len(idxes) == 0 {
117-
return "", nil
118-
}
119-
120-
var idxesStr string
121-
for _, idx := range idxes {
122-
var idxStr string
123-
idxStr = fmt.Sprintf("%s: (", idx.Index.Index.Table.L)
124-
cols := idx.Index.Index.Columns
125-
colLen := len(cols)
126-
127-
for i := 0; i < len(cols)-1; i++ {
128-
idxStr = fmt.Sprintf("%s%s ", idxStr, cols[i].Name.L)
129-
}
130-
131-
idxStr = fmt.Sprintf("%s%s)", idxStr, cols[colLen-1].Name.L)
132-
idxesStr = fmt.Sprintf("%s%s,", idxesStr, idxStr)
133-
}
134-
return idxesStr[:len(idxesStr)-1], nil
135-
}
136-
}
137-
13899
// Init set session variable tidb_enable_index_advisor = true
139100
func (ia *IdxAdvisor) Init() error {
140101
ia.queryChan = make(chan string, queryChanSize)
@@ -168,7 +129,7 @@ func (ia *IdxAdvisor) StartTask(sqlFile string) {
168129
query, ok := <-ia.queryChan
169130
if !ok {
170131
// No more query
171-
WriteFinaleResult()
132+
WriteFinalResult()
172133
return
173134
}
174135
fmt.Printf("**************************************[%v]******************************************\n", cnt)
@@ -177,93 +138,6 @@ func (ia *IdxAdvisor) StartTask(sqlFile string) {
177138
}
178139
}
179140

180-
//func readQuery(sqlFile *string, queryChan chan string) {
181-
// fd, _ := os.Open(*sqlFile)
182-
// defer func() {
183-
// fd.Close()
184-
// close(queryChan)
185-
// }()
186-
//
187-
// scanner := bufio.NewScanner(fd)
188-
//
189-
// // TODO: more efficient way to extract select statement from file
190-
// maxCap := bufio.MaxScanTokenSize
191-
// buf := make([]byte, maxCap)
192-
// scanner.Buffer(buf, maxCap)
193-
// split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
194-
// // Define a split function that separates on "--"
195-
// for i := 0; i < len(data)-1; i++ {
196-
// if data[i] == 0x2d && data[i+1] == 0x2d {
197-
// return i + 2, data[:i], nil
198-
//
199-
// }
200-
//
201-
// }
202-
// return 0, data, bufio.ErrFinalToken
203-
// }
204-
// scanner.Split(split)
205-
//
206-
// // Scan
207-
// cnt := 1
208-
// for scanner.Scan() {
209-
// contents := scanner.Text()
210-
// // fmt.Printf("================================[%v]==================================\n", cnt)
211-
// // fmt.Printf("%v\n", contents)
212-
// sqlBegin := strings.Index(string(contents), "select")
213-
// query := contents[sqlBegin : len(contents)-1]
214-
// queryChan <- query
215-
// cnt++
216-
// }
217-
//
218-
// if err := scanner.Err(); err != nil {
219-
// fmt.Fprintln(os.Stderr, "reading input:", err)
220-
// }
221-
//}
222-
223-
func readQuery(sqlFile string, queryChan chan string) {
224-
defer func() {
225-
close(queryChan)
226-
}()
227-
228-
// If readQuery is called in idxadv_test.go, return immediately
229-
if sqlFile == "test-mode" {
230-
return
231-
}
232-
233-
files, err := ioutil.ReadDir(sqlFile)
234-
if err != nil {
235-
panic(err)
236-
}
237-
238-
n := len(files)
239-
240-
for i := 1; i <= n; i++ {
241-
sqlfile := sqlFile + strconv.Itoa(i) + ".sql"
242-
243-
contents, err := ioutil.ReadFile(sqlfile)
244-
if err != nil {
245-
panic(err)
246-
}
247-
// sqlBegin := strings.Index(string(contents), "select")
248-
// query := contents[sqlBegin:]
249-
queryChan <- string(contents)
250-
}
251-
}
252-
253-
/*
254-
// StartTask start handling queries in idxadv mode after session variable tidb_enable_index_advisor has been set
255-
func (ia *IdxAdvisor) StartTask(query string) {
256-
if ia.IsReady() {
257-
// var err error
258-
sqlFile := "/tmp/queries"
259-
queries := readQuery(&sqlFile)
260-
for i, query := range queries {
261-
fmt.Printf("$$$$$$$$$$$$$$$$$$$$$$[%v]$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n", i+1)
262-
ia.dbClient.Exec(query)
263-
}
264-
}
265-
}
266-
*/
267141
func GetVirtualInfoschema(is infoschema.InfoSchema, dbName string, tableInfoSets map[string]*plannercore.TableInfoSets) infoschema.InfoSchema {
268142
// Get a copy of InfoSchema
269143
dbInfos := is.Clone()
@@ -280,7 +154,7 @@ func GetVirtualInfoschema(is infoschema.InfoSchema, dbName string, tableInfoSets
280154
idxInfo := tblCopy.Meta().Indices
281155

282156
// add virtual indexes to InfoSchemaCopy.TblInfo
283-
virtualIndexes := BuildVirtualIndexes(tblInfoCopy, dbname, tblname, tblInfoSets)
157+
virtualIndexes := buildVirtualIndexes(tblInfoCopy, dbname, tblname, tblInfoSets)
284158
for _, virtualIndex := range virtualIndexes {
285159
if !isExistedInTable(virtualIndex, idxInfo) {
286160
tblInfoCopy.Indices = append(tblInfoCopy.Indices, virtualIndex)
@@ -290,14 +164,14 @@ func GetVirtualInfoschema(is infoschema.InfoSchema, dbName string, tableInfoSets
290164
return ISCopy
291165
}
292166

293-
func BuildVirtualIndexes(tblInfo *model.TableInfo, dbname, tblname model.CIStr, tblInfoSets *plannercore.TableInfoSets) []*model.IndexInfo {
294-
indexes := GenVirtualIndexCols(tblInfo, dbname, tblname, tblInfoSets)
167+
func buildVirtualIndexes(tblInfo *model.TableInfo, dbname, tblname model.CIStr, tblInfoSets *plannercore.TableInfoSets) []*model.IndexInfo {
168+
indexes := genVirtualIndexCols(tblInfo, dbname, tblname, tblInfoSets)
295169
result := make([]*model.IndexInfo, 0)
296170
for i, idxColNames := range indexes {
297171
indexName := model.NewCIStr("vIndex" + string(i))
298172
indexinfo, err := ddl.BuildIndexInfo(tblInfo, indexName, idxColNames, model.StatePublic)
299173
if err != nil {
300-
fmt.Printf("BuildVirtualIndexes error: %v!\n", err)
174+
fmt.Printf("buildVirtualIndexes error: %v!\n", err)
301175
var idxColNameStr string
302176
for _, idxCol := range idxColNames {
303177
idxColNameStr = fmt.Sprintf("%v %v", idxColNameStr, idxCol)
@@ -310,14 +184,14 @@ func BuildVirtualIndexes(tblInfo *model.TableInfo, dbname, tblname model.CIStr,
310184
return result
311185
}
312186

313-
func GenVirtualIndexCols(tblInfo *model.TableInfo, dbname, tblname model.CIStr, tblInfoSets *plannercore.TableInfoSets) [][]*ast.IndexColName {
187+
func genVirtualIndexCols(tblInfo *model.TableInfo, dbname, tblname model.CIStr, tblInfoSets *plannercore.TableInfoSets) [][]*ast.IndexColName {
314188
columnInfos := tblInfo.Columns
315189
var result [][]*ast.IndexColName
316190

317191
// one column
318192
for _, columnInfo := range columnInfos {
319193
idxCols := make([]*ast.IndexColName, 1, 1)
320-
idxCols[0] = BuildIdxColNameFromColInfo(columnInfo, dbname, tblname)
194+
idxCols[0] = buildIdxColNameFromColInfo(columnInfo, dbname, tblname)
321195
result = append(result, idxCols)
322196
}
323197

@@ -327,8 +201,8 @@ func GenVirtualIndexCols(tblInfo *model.TableInfo, dbname, tblname model.CIStr,
327201
for j := 0; j < nCols; j++ {
328202
if i != j {
329203
idxTwoCols := make([]*ast.IndexColName, 2, 2)
330-
idxTwoCols[0] = BuildIdxColNameFromColInfo(columnInfos[i], dbname, tblname)
331-
idxTwoCols[1] = BuildIdxColNameFromColInfo(columnInfos[j], dbname, tblname)
204+
idxTwoCols[0] = buildIdxColNameFromColInfo(columnInfos[i], dbname, tblname)
205+
idxTwoCols[1] = buildIdxColNameFromColInfo(columnInfos[j], dbname, tblname)
332206
result = append(result, idxTwoCols)
333207
}
334208
}
@@ -391,12 +265,11 @@ func GenVirtualIndexCols(tblInfo *model.TableInfo, dbname, tblname model.CIStr,
391265
}
392266
}
393267
if isExisted {
394-
idxCols = append(idxCols, BuildIdxColNameFromColInfo(columnInfo, dbname, tblname))
268+
idxCols = append(idxCols, buildIdxColNameFromColInfo(columnInfo, dbname, tblname))
395269
}
396270
}
397271
result = append(result, idxCols)
398272
}
399-
400273
return result
401274
}
402275

@@ -412,26 +285,18 @@ func addToCandidateCols(readyCols []model.CIStr, cols *[]model.CIStr, candidateC
412285
}
413286
}
414287

415-
func BuildIdxColNameFromColInfo(colInfo *model.ColumnInfo, dbname, tblname model.CIStr) *ast.IndexColName {
288+
func buildIdxColNameFromColInfo(colInfo *model.ColumnInfo, dbname, tblname model.CIStr) *ast.IndexColName {
416289
idxColName := &ast.IndexColName{}
417290
idxColName.Column = &ast.ColumnName{Schema: dbname, Table: tblname, Name: colInfo.Name}
418291
idxColName.Length = -1
419292
return idxColName
420293
}
421294

422-
func GenIndexCols(index *model.IndexInfo) []model.CIStr {
423-
cols := []model.CIStr{}
424-
for _, idxColumn := range index.Columns {
425-
cols = append(cols, idxColumn.Name)
426-
}
427-
return cols
428-
}
429-
430295
func isExistedInTable(virtualIndex *model.IndexInfo, indices []*model.IndexInfo) bool {
431296
is := false
432-
virtualIndexCols := GenIndexCols(virtualIndex)
297+
virtualIndexCols := genIndexCols(virtualIndex)
433298
for _, idx := range indices {
434-
indexCols := GenIndexCols(idx)
299+
indexCols := genIndexCols(idx)
435300
if reflect.DeepEqual(virtualIndexCols, indexCols) {
436301
is = true
437302
break
@@ -440,6 +305,14 @@ func isExistedInTable(virtualIndex *model.IndexInfo, indices []*model.IndexInfo)
440305
return is
441306
}
442307

308+
func genIndexCols(index *model.IndexInfo) []model.CIStr {
309+
cols := []model.CIStr{}
310+
for _, idxColumn := range index.Columns {
311+
cols = append(cols, idxColumn.Name)
312+
}
313+
return cols
314+
}
315+
443316
func (ia *IdxAdvisor) addCandidate(virtualIdx *CandidateIdx) {
444317
in := false
445318
for _, candidateIdx := range ia.Candidate_idx {
@@ -454,3 +327,31 @@ func (ia *IdxAdvisor) addCandidate(virtualIdx *CandidateIdx) {
454327
ia.Candidate_idx = append(ia.Candidate_idx, virtualIdx)
455328
}
456329
}
330+
331+
func readQuery(sqlFile string, queryChan chan string) {
332+
defer func() {
333+
close(queryChan)
334+
}()
335+
336+
// If readQuery is called in idxadv_test.go, return immediately
337+
if sqlFile == "test-mode" {
338+
return
339+
}
340+
341+
files, err := ioutil.ReadDir(sqlFile)
342+
if err != nil {
343+
panic(err)
344+
}
345+
346+
n := len(files)
347+
348+
for i := 1; i <= n; i++ {
349+
sqlfile := sqlFile + strconv.Itoa(i) + ".sql"
350+
351+
contents, err := ioutil.ReadFile(sqlfile)
352+
if err != nil {
353+
panic(err)
354+
}
355+
queryChan <- string(contents)
356+
}
357+
}

0 commit comments

Comments
 (0)