You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化多模型Django查询,提升大数据量下的执行速度?

优化多模型得分统计的查询效率

你当前代码效率低的核心原因:

  • 循环40个模型分别查询,每次都把符合日期条件的全量对象拉到Python内存里再求和,既做了40次数据库请求,又传输了大量不必要的数据。
  • 没有利用数据库的聚合计算能力,把本该数据库做的计算丢给了Python。

1. 用数据库聚合替代Python求和

直接让数据库计算每个模型的总分,每次查询只返回一个数值,大幅减少数据传输量:

from django.db.models import Sum

campaign_score = 0
for model in campaign_list:
    # 用Sum聚合函数在数据库层面完成求和
    score_agg = model.objects.filter(audit_date__range=[start_date, todays_date]).aggregate(total=Sum('overall_score'))
    # 处理无数据的情况(此时total为None)
    campaign_score += score_agg['total'] or 0

2. 给日期字段加索引

每个模型的audit_date字段添加数据库索引,能显著加速日期范围查询:

在模型类的Meta中添加索引:

class ExampleModel(models.Model):
    audit_date = models.DateField()
    overall_score = models.FloatField()
    # 其他字段...

    class Meta:
        indexes = [models.Index(fields=['audit_date'])]

执行迁移生效:python manage.py makemigrations && python manage.py migrate

3. 针对「每月平均分」的精准优化

如果你的核心需求是按月份统计平均分,直接用数据库分组聚合,一次性拿到每个月的总分和数据量,再计算平均:

from django.db.models import Sum, Count
from django.db.models.functions import ExtractMonth, ExtractYear

monthly_data = []
for model in campaign_list:
    # 按年、月分组,统计每组的总分和数据量
    model_monthly = model.objects.filter(audit_date__range=[start_date, todays_date]).annotate(
        year=ExtractYear('audit_date'),
        month=ExtractMonth('audit_date')
    ).values('year', 'month').annotate(
        total_score=Sum('overall_score'),
        record_count=Count('id')
    ).order_by('year', 'month')
    
    monthly_data.extend(model_monthly)

# 合并不同模型的同月数据,计算最终平均分
final_monthly_avg = {}
for item in monthly_data:
    key = (item['year'], item['month'])
    if key not in final_monthly_avg:
        final_monthly_avg[key] = {'total': 0, 'count': 0}
    final_monthly_avg[key]['total'] += item['total_score'] or 0
    final_monthly_avg[key]['count'] += item['record_count'] or 0

# 输出结果
for (year, month), stats in final_monthly_avg.items():
    if stats['count'] > 0:
        avg = stats['total'] / stats['count']
        print(f"{year}年{month}月 平均分:{avg:.2f}")

进阶建议:合并模型(如果结构一致)

如果这40个模型的字段完全相同,建议改成单表+类型字段的结构(比如新增campaign_type字段区分不同业务类型),这样只需要一次查询就能完成所有统计,效率会提升数十倍。


内容的提问来源于stack exchange,提问作者Ibrahim Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:30:24