Skip to content

Commit

Permalink
Merge pull request #2147 from actiontech/modify-index-advice
Browse files Browse the repository at this point in the history
fix: panic when accept a nil where stmt
  • Loading branch information
sjjian authored Dec 12, 2023
2 parents 2419692 + cc60636 commit 2f226fd
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 121 deletions.
57 changes: 39 additions & 18 deletions sqle/driver/mysql/advisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import (
const (
MAX_INDEX_COLUMN string = "composite_index_max_column"
MAX_INDEX_COLUMN_DEFAULT_VALUE int = 5
threeStarIndexAdviceFormat string = "索引建议 | 根据三星索引设计规范,建议对表%s添加复合索引:【%s】"
prefixIndexAdviceFormat string = "索引建议 | SQL使用了前缀模式匹配,数据量大时,可建立翻转函数索引"
extremalIndexAdviceFormat string = "索引建议 | SQL使用了最值函数,可以利用索引有序的性质快速找到最值,建议对表%s添加单列索引,参考列:%s"
functionIndexAdviceFormatV80 string = "索引建议 | SQL使用了函数作为查询条件,在MySQL8.0.13以上的版本,可以创建函数索引,建议对表%s添加函数索引,参考列:%s"
functionIndexAdviceFormatV57 string = "索引建议 | SQL使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,建议对表%s添加虚拟列索引,参考列:%s"
functionIndexAdviceFormatAll string = "索引建议 | SQL使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,在MySQL8.0.13以上的版本,可以创建函数索引,建议根据MySQL版本对表%s添加合适的索引,参考列:%s"
joinIndexAdviceFormat string = "索引建议 | SQL中字段%s为被驱动表%s上的关联字段,建议对表%s添加单列索引,参考列:%s"
)

type OptimizeResult struct {
Expand Down Expand Up @@ -345,10 +352,12 @@ func (a *threeStarIndexAdvisor) GiveAdvices() []*OptimizeResult {
if util.IsIndex(a.adviceColumns.columnMap, a.drivingTableCreateStmt.Constraints) {
return nil
}
tableName := util.GetTableNameFromTableSource(a.drivingTableSource)
indexColumns := a.adviceColumns.stringSlice()
return []*OptimizeResult{{
TableName: util.GetTableNameFromTableSource(a.drivingTableSource),
IndexedColumns: a.adviceColumns.stringSlice(),
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,根据三星索引设计规范", restore(a.originNode)),
TableName: tableName,
IndexedColumns: indexColumns,
Reason: fmt.Sprintf(threeStarIndexAdviceFormat, tableName, strings.Join(indexColumns, ",")),
}}
}

Expand Down Expand Up @@ -680,6 +689,9 @@ func newJoinIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode ast
}

func (a *joinIndexAdvisor) GiveAdvices() []*OptimizeResult {
if a.originNode == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when join index advisor load essentials failed, err:%v", err)
Expand Down Expand Up @@ -780,7 +792,7 @@ func (a *joinIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: drivenTableName,
IndexedColumns: indexColumn,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,字段 %s 为被驱动表 %s 上的关联字段", restore(a.currentNode), strings.Join(indexColumn, ","), drivenTableName),
Reason: fmt.Sprintf(joinIndexAdviceFormat, strings.Join(indexColumn, ","), drivenTableName, drivenTableName, strings.Join(indexColumn, ",")),
})
}

Expand Down Expand Up @@ -841,15 +853,18 @@ func newFunctionIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode
}

func (a *functionIndexAdvisor) GiveAdvices() []*OptimizeResult {
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
if node.Where == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when function index advisor load essentials failed, err:%v", err)
return nil
}
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
node.Where.Accept(a)
return a.advices
}
Expand Down Expand Up @@ -917,23 +932,23 @@ func (a *functionIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatV57, tableName, strings.Join(columns, ",")),
})
return
}
if curVersion != nil && curVersion.GreaterThan(semver.MustParse("8.0.12")) {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL8.0.13以上的版本,可以创建函数索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatV80, tableName, strings.Join(columns, ",")),
})
return
}
// 某些版本解析会出错,例如"8.0.35-0<system_name>0.22.04.1"
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: columns,
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了函数作为查询条件,在MySQL5.7以上的版本,可以在虚拟列上创建索引,在MySQL8.0.13以上的版本,可以创建函数索引", restore(a.currentNode.L)),
Reason: fmt.Sprintf(functionIndexAdviceFormatAll, tableName, strings.Join(columns, ",")),
})
}

Expand Down Expand Up @@ -966,6 +981,9 @@ func newExtremalIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode
}

func (a *extremalIndexAdvisor) GiveAdvices() []*OptimizeResult {
if a.originNode == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when extremal index advisor load essentials failed, err:%v", err)
Expand Down Expand Up @@ -1027,7 +1045,7 @@ func (a *extremalIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: []string{indexColumn},
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了最值函数,可以利用索引有序的性质快速找到最值", restore(a.currentNode)),
Reason: fmt.Sprintf(extremalIndexAdviceFormat, tableName, indexColumn),
})
}

Expand Down Expand Up @@ -1056,15 +1074,18 @@ func newPrefixIndexAdvisor(ctx *session.Context, log *logrus.Entry, originNode a
}

func (a *prefixIndexAdvisor) GiveAdvices() []*OptimizeResult {
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
if node.Where == nil {
return nil
}
err := a.loadEssentials()
if err != nil {
a.log.Logger.Warnf("when prefix index advisor load essentials failed, err:%v", err)
return nil
}
node, ok := a.originNode.(*ast.SelectStmt)
if !ok {
return nil
}
node.Where.Accept(a)
return a.advices
}
Expand Down Expand Up @@ -1100,7 +1121,7 @@ func (v *prefixIndexAdvisor) Leave(in ast.Node) (out ast.Node, ok bool) {
}

func (a *prefixIndexAdvisor) giveAdvice() {
if !util.CheckWhereFuzzySearch(a.currentNode) {
if !util.CheckWhereLeftFuzzySearch(a.currentNode) {
return
}
column, ok := a.currentNode.Expr.(*ast.ColumnNameExpr)
Expand All @@ -1116,6 +1137,6 @@ func (a *prefixIndexAdvisor) giveAdvice() {
a.advices = append(a.advices, &OptimizeResult{
TableName: tableName,
IndexedColumns: []string{column.Name.Name.L},
Reason: fmt.Sprintf("索引建议 | SQL:%s 中,使用了前缀模式匹配,在数据量大的时候,可以建立翻转函数索引", restore(a.currentNode)),
Reason: prefixIndexAdviceFormat,
})
}
Loading

0 comments on commit 2f226fd

Please sign in to comment.