@@ -14,6 +14,7 @@ import (
1414 "github.com/actiontech/sqle/sqle/driver/mysql/plocale"
1515 rulepkg "github.com/actiontech/sqle/sqle/driver/mysql/rule"
1616 _ "github.com/actiontech/sqle/sqle/driver/mysql/rule/ai"
17+ aiutil "github.com/actiontech/sqle/sqle/driver/mysql/rule/ai/util"
1718 "github.com/actiontech/sqle/sqle/driver/mysql/session"
1819 "github.com/actiontech/sqle/sqle/driver/mysql/util"
1920 driverV2 "github.com/actiontech/sqle/sqle/driver/v2"
@@ -639,6 +640,83 @@ func (p *PluginProcessor) GetDriverMetas() (*driverV2.DriverMetas, error) {
639640 return metas , nil
640641}
641642
643+ func (i * MysqlDriverImpl ) GetSelectivityOfSQLColumns (ctx context.Context , sql string ) (map [string ]map [string ]float32 , error ) {
644+ node , err := util .ParseOneSql (sql )
645+ if err != nil {
646+ return nil , err
647+ }
648+
649+ if _ , ok := node .(* ast.SelectStmt ); ! ok {
650+ log .NewEntry ().Errorf ("get selectivity of sql columns failed, sql is not a select statement, sql: %s" , sql )
651+ return nil , nil
652+ }
653+
654+ selectVisitor := & util.SelectVisitor {}
655+ node .Accept (selectVisitor )
656+
657+ result := make (map [string ]map [string ]float32 )
658+
659+ for _ , selectNode := range selectVisitor .SelectList {
660+ if selectNode .From == nil || selectNode .From .TableRefs == nil {
661+ continue
662+ }
663+
664+ // 获取表别名映射关系
665+ aliasInfo := aiutil .GetTableAliasInfoFromJoin (selectNode .From .TableRefs )
666+ aliasMap := make (map [string ]string )
667+ allTables := make ([]string , 0 , len (aliasInfo ))
668+
669+ for _ , alias := range aliasInfo {
670+ if alias .TableAliasName != "" {
671+ aliasMap [alias .TableAliasName ] = alias .TableName
672+ }
673+ allTables = append (allTables , alias .TableName )
674+ }
675+
676+ // 提取列并按表分组
677+ tableColumns := util .ExtractColumnsFromSelectStmt (selectNode , aliasMap , allTables )
678+
679+ // 遍历每个表,获取其列的选择性
680+ for tableName , columnSet := range tableColumns {
681+ columns := make ([]string , 0 , len (columnSet ))
682+ for colName := range columnSet {
683+ columns = append (columns , colName )
684+ }
685+
686+ if len (columns ) == 0 {
687+ continue
688+ }
689+
690+ // 构造 TableName 对象
691+ var schemaName string
692+ for _ , alias := range aliasInfo {
693+ if alias .TableName == tableName {
694+ schemaName = alias .SchemaName
695+ break
696+ }
697+ }
698+ tableNameObj := util .NewTableName (schemaName , tableName )
699+
700+ columnSelectivityMap , err := i .Ctx .GetSelectivityOfColumns (tableNameObj , columns )
701+ if err != nil {
702+ log .NewEntry ().Errorf ("get selectivity of columns failed, table: %s, columns: %v, error: %v" , tableName , columns , err )
703+ continue
704+ }
705+
706+ if result [tableName ] == nil {
707+ result [tableName ] = make (map [string ]float32 )
708+ }
709+ for columnName , selectivity := range columnSelectivityMap {
710+ if selectivity > 0 {
711+ result [tableName ][columnName ] = float32 (selectivity )
712+ }
713+ }
714+ }
715+ }
716+
717+ return result , nil
718+ }
719+
642720func (p * PluginProcessor ) Open (l * logrus.Entry , cfg * driverV2.Config ) (driver.Plugin , error ) {
643721 return NewInspect (l , cfg )
644722}
0 commit comments