🏎️ perf: optimize aggregated model look-ups by batching bound-channel queries
Summary
-------
1. **Backend**
• `model/model_meta.go`
– Add `GetBoundChannelsForModels([]string)` to retrieve channels for multiple models in a single SQL (`IN (?)`) and deduplicate with `GROUP BY`.
• `controller/model_meta.go`
– In non-exact `fillModelExtra`:
– Remove per-model `GetBoundChannels` calls.
– Collect matched model names, then call `GetBoundChannelsForModels` once and merge results into `channelSet`.
– Minor cleanup on loop logic; channel aggregation now happens after quota/group/endpoint processing.
Impact
------
• Eliminates N+1 query pattern for prefix/suffix/contains rules.
• Reduces DB round-trips from *N + 1* to **1**, markedly speeding up the model-management list load.
• Keeps existing `GetBoundChannels` API intact for single-model scenarios; no breaking changes.
This commit is contained in:
@@ -188,6 +188,7 @@ func fillModelExtra(m *model.Model) {
|
||||
|
||||
// 端点去重集合
|
||||
endpointSet := make(map[constant.EndpointType]struct{})
|
||||
|
||||
// 已绑定渠道去重集合
|
||||
channelSet := make(map[string]model.BoundChannel)
|
||||
// 分组去重集合
|
||||
@@ -224,14 +225,6 @@ func fillModelExtra(m *model.Model) {
|
||||
|
||||
// 收集计费类型
|
||||
quotaTypeSet[p.QuotaType] = struct{}{}
|
||||
|
||||
// 收集渠道
|
||||
if channels, err := model.GetBoundChannels(p.ModelName); err == nil {
|
||||
for _, ch := range channels {
|
||||
key := ch.Name + "_" + strconv.Itoa(ch.Type)
|
||||
channelSet[key] = ch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 序列化端点
|
||||
@@ -245,15 +238,6 @@ func fillModelExtra(m *model.Model) {
|
||||
}
|
||||
}
|
||||
|
||||
// 序列化渠道
|
||||
if len(channelSet) > 0 {
|
||||
channels := make([]model.BoundChannel, 0, len(channelSet))
|
||||
for _, ch := range channelSet {
|
||||
channels = append(channels, ch)
|
||||
}
|
||||
m.BoundChannels = channels
|
||||
}
|
||||
|
||||
// 序列化分组
|
||||
if len(groupSet) > 0 {
|
||||
groups := make([]string, 0, len(groupSet))
|
||||
@@ -272,6 +256,23 @@ func fillModelExtra(m *model.Model) {
|
||||
m.QuotaType = -1
|
||||
}
|
||||
|
||||
// 批量查询并序列化渠道
|
||||
if len(matchedNames) > 0 {
|
||||
if channels, err := model.GetBoundChannelsForModels(matchedNames); err == nil {
|
||||
for _, ch := range channels {
|
||||
key := ch.Name + "_" + strconv.Itoa(ch.Type)
|
||||
channelSet[key] = ch
|
||||
}
|
||||
}
|
||||
if len(channelSet) > 0 {
|
||||
chs := make([]model.BoundChannel, 0, len(channelSet))
|
||||
for _, ch := range channelSet {
|
||||
chs = append(chs, ch)
|
||||
}
|
||||
m.BoundChannels = chs
|
||||
}
|
||||
}
|
||||
|
||||
// 设置匹配信息
|
||||
m.MatchedModels = matchedNames
|
||||
m.MatchedCount = len(matchedNames)
|
||||
|
||||
Reference in New Issue
Block a user