django聚合SUM是否已缓存?还是每次都会计算?

时间:2018-10-16 12:30:59

标签: python django

假设我有一个交易模型:

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等,当我更新交易模型时,也会更新所有其他模型。

这样,当用户请求数据时,我从“缓存”汇总数据的模型中获取数据,而无需执行任何操作,它只是从各个表中检索数据,这很多比交易之一小。

这种方法的问题在于它实际上可能不是更快,不是那么灵活,并且在更新所有模型时如果出现任何问题,数据可能会混乱。

1 个答案:

答案 0 :(得分:3)

所以要回答您的问题,是和否。查询集(Transaction.objects.filter(...))在求值时确实会被缓存,但这通常不是问题。

您担心的是实际的聚合查询。因此,首先让我回答您的一般性问题,然后再解释原因...

  1. 这有多快?
    • 很快
  2. 如果表增长到具有数百万个条目,会发生什么?
    • 没什么,只要索引正确的列就可以了。
  3. 如何确保已对其进行优化?
    • 您不必这样做,Django会帮您做到这一点(大部分时间)。
  4. Django是否从Sum缓存值?
    • 是,不是。它缓存评估的查询集,但不缓存查询本身。

大局是我们在这里需要解释的。 Django查询集可转换为SQL。从字面上看,此SQL的构建是为了进行您要进行的查询。 Transaction.objects.filter(...).aggregate(...)的SQL看起来像

SELECT some_aggregate_func(*)
FROM myapp_transaction
WHERE [insert filters here];

您关于将数据分为多个表的想法实际上是一个非常糟糕的想法。最终将减慢写入速度,并使查询复杂化。最终还会造成重复数据的噩梦,让您管理。请参阅{matt-salzman提供的link,有关处理大量数据的数据库。