🏎️ 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:
@@ -139,6 +139,21 @@ func GetBoundChannels(modelName string) ([]BoundChannel, error) {
|
||||
return channels, err
|
||||
}
|
||||
|
||||
// GetBoundChannelsForModels 批量查询多模型的绑定渠道并去重返回
|
||||
func GetBoundChannelsForModels(modelNames []string) ([]BoundChannel, error) {
|
||||
if len(modelNames) == 0 {
|
||||
return make([]BoundChannel, 0), nil
|
||||
}
|
||||
var channels []BoundChannel
|
||||
err := DB.Table("channels").
|
||||
Select("channels.name, channels.type").
|
||||
Joins("join abilities on abilities.channel_id = channels.id").
|
||||
Where("abilities.model IN ? AND abilities.enabled = ?", modelNames, true).
|
||||
Group("channels.id").
|
||||
Scan(&channels).Error
|
||||
return channels, err
|
||||
}
|
||||
|
||||
// FindModelByNameWithRule 根据模型名称和匹配规则查找模型元数据,优先级:精确 > 前缀 > 后缀 > 包含
|
||||
func FindModelByNameWithRule(name string) (*Model, error) {
|
||||
// 1. 精确匹配
|
||||
|
||||
Reference in New Issue
Block a user