假设我有一个交易模型:
class Transaction(models.Model):
receiver = models.CharField(unique=True)
value = models.DecimalField(max_digits=10, decimal_places=5)
date = models.DateField()
现在,我有成千上万的交易进入表中。
我需要向接收者显示每天,每周,每月,每年等的交易情况。
我可以使用以下语句来做到这一点:
from django.db.models import Sum
transactions = Transaction.objects.filter(receiver="name").aggregate(Sum('value'))
,然后根据需要的日期进行过滤。示例:
transactions.filter(date__gte=start_date, date__lte=end_date)
这有多快?如果表增长到具有数百万个条目,会发生什么?如何确保已对其进行优化? django是否会缓存Sum中的值?
我天真地思考如何进行优化的方式是创建更多模型: DayTransaction,MonthTransaction,YearTransaction等,当我更新交易模型时,也会更新所有其他模型。
这样,当用户请求数据时,我从“缓存”汇总数据的模型中获取数据,而无需执行任何操作,它只是从各个表中检索数据,这很多比交易之一小。
这种方法的问题在于它实际上可能不是更快,不是那么灵活,并且在更新所有模型时如果出现任何问题,数据可能会混乱。
答案 0 :(得分:3)
所以要回答您的问题,是和否。查询集(Transaction.objects.filter(...)
)在求值时确实会被缓存,但这通常不是问题。
您担心的是实际的聚合查询。因此,首先让我回答您的一般性问题,然后再解释原因...
大局是我们在这里需要解释的。 Django查询集可转换为SQL。从字面上看,此SQL的构建是为了进行您要进行的查询。 Transaction.objects.filter(...).aggregate(...)
的SQL看起来像
SELECT some_aggregate_func(*)
FROM myapp_transaction
WHERE [insert filters here];
您关于将数据分为多个表的想法实际上是一个非常糟糕的想法。最终将减慢写入速度,并使查询复杂化。最终还会造成重复数据的噩梦,让您管理。请参阅{matt-salzman提供的link,有关处理大量数据的数据库。