
对于不超过 2000 行的 django queryset,无需引入 pandas 或 numpy,仅用原生 `.aggregate()` 即可高效完成均值、求和、计数等常见统计操作,且全部在数据库层执行,性能更优、内存更省。
在 Django 开发中,面对中等规模(如 ≤2000 条)的数据聚合需求(例如按条件计算某字段均值、另一字段求和、或匹配行数),许多开发者习惯先 list(queryset) 转为 Python 列表,再用内置函数或第三方库处理——但这不仅冗余加载数据到应用内存,还错失了数据库原生聚合能力。实际上,Django 提供了强大而轻量的 .aggregate() 方法,它将计算逻辑下推至数据库(如 PostgreSQL、MySQL),由数据库引擎直接完成统计,一次查询、零数据搬运、低内存占用、高执行效率。
以问题中的示例为例(筛选 T1_id == 1 的记录,计算 T1_value 均值、T2_value 总和、匹配行数),正确做法是:
from django.db.models import Avg, Sum, Count
result = MyModel.objects.filter(T1_id=1).aggregate(
x1=Avg('T1_value'),
x2=Sum('T2_value'),
x3=Count('*') # 或 Count('id'),' * ' 表示统计所有匹配行(含 NULL)
)
# 返回字典,如:{'x1': 2.0, 'x2': 0, 'x3': 1}
print(result['x1'], result['x2'], result['x3'])✅ 优势说明:
- 性能优越:数据库直接计算,避免将全部字段数据从 DB 传输至 Python 进程;尤其在字段较多或网络延迟明显时,提速显著。
- 内存友好:无论 QuerySet 实际含多少字段,.aggregate() 仅返回几个标量值,无额外内存压力。
- 语法简洁:无需手动遍历、过滤或调用 statistics.mean() 等,语义清晰,符合 Django ORM 设计哲学。
- 完全免依赖:不引入任何外部包,部署轻量,适合资源受限环境(如小型服务器、Serverless 场景)。
⚠️ 注意事项:
- 若需对同一 QuerySet 执行多组不同条件的聚合(如同时统计 T1_id=1 和 T1_id=2 的结果),应使用 Case + When 配合 Sum(Avg(...)) 等组合,或分多次 .aggregate() 查询(仍远优于全量取数);
- Count('*') 统计所有匹配行(包括某字段为 NULL 的行),若需排除 NULL,可改用 Count('field_name');
- 确保相关字段已建立数据库索引(如 T1_id),可进一步加速 filter() + aggregate() 的联合执行。
总之,当目标明确、逻辑简单、数据量适中时,优先使用 Django 内置聚合而非“取数再计算”——这是兼顾可维护性、性能与简洁性的最佳实践。










