【问题标题】:Is django aggregate SUM cached? Or does it calculate every time?django 聚合 SUM 是否缓存?还是每次都计算?
【发布时间】:2019-03-20 23:46:41
【问题描述】:

假设我有一个 Transaction 模型:

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

这样,当用户请求数据时,我从“缓存”汇总数据的模型中获取它,它不需要做任何操作,它只是从各个表中检索数据,这很多小于事务一。

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

【问题讨论】:

标签: python django


【解决方案1】:

所以回答你的问题,是和不是。查询集 (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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 2010-11-26
    • 2011-03-09
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多