Files
kra-new/internal/data/business/query_indexes.go
T

84 lines
3.3 KiB
Go

package business
import (
"fmt"
"strings"
"gorm.io/gorm"
)
type businessQueryIndex struct {
table, name string
columns []string
}
var businessQueryIndexes = []businessQueryIndex{
{"tab_promote", "idx_sw_promote_created", []string{"source_db", "create_time", "id"}},
{"tab_spend", "idx_sw_spend_time_summary", []string{"pay_status", "pay_time", "source_db", "pay_amount"}},
{"tab_spend", "idx_sw_spend_promote_summary", []string{"promote_id", "pay_status", "source_db", "pay_amount"}},
{"tab_sw_report_day", "idx_sw_report_pay_scan", []string{"dedup_mode", "stat_date", "source_db", "promote_id", "game_id", "total_pay"}},
{"tab_sw_report_day_key", "idx_sw_report_key_scan", []string{"dedup_mode", "stat_date", "source_db", "promote_id", "game_id", "metric", "identity_key"}},
{"tab_sw_report_server_day", "idx_sw_server_pay_game_scan", []string{"game_name", "dedup_mode", "stat_date", "source_db", "game_id", "server_num", "total_pay"}},
{"tab_sw_report_server_day_key", "idx_sw_server_key_game_scan", []string{"game_name", "dedup_mode", "stat_date", "source_db", "game_id", "server_num", "metric", "identity_key"}},
}
var reportBuildQueryIndexes = []businessQueryIndex{
{"tab_user", "idx_sw_user_report_identity", []string{"id", "source_db", "puid", "promote_id", "idcard"}},
{"tab_user_play_info", "idx_sw_play_report_active", []string{"play_time", "user_id", "source_db", "promote_id", "game_id", "server_id"}},
}
// 只为已经接入的业务表增加索引,不创建平台表、不改写记录。
// 按实际筛选前缀排列,并覆盖聚合读取列,避免大范围回表。
func migrateBusinessQueryIndexes(db *gorm.DB) error {
return migrateQueryIndexes(db, businessQueryIndexes)
}
func migrateReportBuildQueryIndexes(db *gorm.DB) error {
return migrateQueryIndexes(db, reportBuildQueryIndexes)
}
func migrateQueryIndexes(db *gorm.DB, indexes []businessQueryIndex) error {
if db.Dialector.Name() != "mysql" {
return nil
}
groups := make(map[string][]businessQueryIndex)
tables := []string{}
for _, index := range indexes {
if _, exists := groups[index.table]; !exists {
tables = append(tables, index.table)
}
groups[index.table] = append(groups[index.table], index)
}
for _, table := range tables {
available, err := businessTableAvailable(db, table)
if err != nil {
return err
}
if !available {
continue
}
additions := []string{}
for _, index := range groups[table] {
var existing []string
if err := db.Raw("SELECT column_name FROM information_schema.statistics WHERE table_schema=DATABASE() AND table_name=? AND index_name=? ORDER BY seq_in_index", index.table, index.name).Scan(&existing).Error; err != nil {
return err
}
if len(existing) > 0 {
if strings.Join(existing, ",") != strings.Join(index.columns, ",") {
return fmt.Errorf("%s.%s 的现有索引列不符", index.table, index.name)
}
continue
}
columns := "`" + strings.Join(index.columns, "`,`") + "`"
additions = append(additions, "ADD INDEX `"+index.name+"` ("+columns+")")
}
// 同一大表的多个索引合并构建,减少重复扫描。
if len(additions) > 0 {
if err := db.Exec("ALTER TABLE `" + table + "` " + strings.Join(additions, ",") + ", ALGORITHM=INPLACE, LOCK=NONE").Error; err != nil {
return fmt.Errorf("add query indexes on %s: %w", table, err)
}
}
}
return nil
}