perf: use channel index order and avoid redundant metric grouping
This commit is contained in:
@@ -54,6 +54,10 @@ func channelMetricPage(db, roots *gorm.DB, f business.ChannelFilter, o business.
|
||||
index := "idx_sw_user_report_identity"
|
||||
if table == "tab_spend" {
|
||||
index = "idx_sw_spend_promote_summary"
|
||||
} else if !f.IDCardDedup {
|
||||
// Its source/channel prefix supports both filtering and grouped counting,
|
||||
// without sorting the much wider identity index into a temporary table.
|
||||
index = "idx_alert_user_window"
|
||||
}
|
||||
if db.Dialector.Name() == "mysql" && db.Migrator().HasIndex(table, index) {
|
||||
metricTable += " FORCE INDEX (" + index + ")"
|
||||
@@ -112,14 +116,20 @@ func channelMetricPage(db, roots *gorm.DB, f business.ChannelFilter, o business.
|
||||
Score string
|
||||
}
|
||||
if f.SortField == "totalPayAmount" {
|
||||
leaves = leaves.Select("source_db,promote_id,COALESCE(SUM(pay_amount),0) AS score")
|
||||
leaves = leaves.Select("source_db,promote_id AS root_id,promote_id,COALESCE(SUM(pay_amount),0) AS score")
|
||||
} else {
|
||||
leaves = leaves.Select("source_db,promote_id,COUNT(*) AS score")
|
||||
leaves = leaves.Select("source_db,promote_id AS root_id,promote_id,COUNT(*) AS score")
|
||||
}
|
||||
leaves = leaves.Group("source_db,promote_id")
|
||||
q = q.Joins("JOIN (?) leaf ON leaf.source_db=cm.source_db AND leaf.promote_id=cm.leaf_id", leaves).
|
||||
Select("cm.source_db,cm.root_id,SUM(leaf.score) AS score")
|
||||
if err := q.Group("cm.source_db,cm.root_id").Scan(&values).Error; err != nil {
|
||||
if f.IncludeSub {
|
||||
q = q.Joins("JOIN (?) leaf ON leaf.source_db=cm.source_db AND leaf.promote_id=cm.leaf_id", leaves).
|
||||
Select("cm.source_db,cm.root_id,SUM(leaf.score) AS score").Group("cm.source_db,cm.root_id")
|
||||
} else {
|
||||
// A channel's own score needs no membership join or second grouping.
|
||||
// Scores remain internal; pagination below only returns visible roots.
|
||||
q = leaves
|
||||
}
|
||||
if err := q.Scan(&values).Error; err != nil {
|
||||
return nil, business.ErrStorage
|
||||
}
|
||||
for _, value := range values {
|
||||
|
||||
Reference in New Issue
Block a user