以天为单位的日期时间差异的高效计算

时间:2017-10-21 14:22:48

标签: python sql-server django python-2.7 django-1.11

我有一个Django模型,其中包含一个带日期的唯一记录。我目前正在将记录计入天数范围,例如X号码已经过了今天的日期,X将在未来10天内发生,X将在未来30天内发生。 下面的代码是我目前正在使用的代码,它从对模型的records.objects.all()查询中提取所有值,然后循环遍历每个对象以计算日期时间增量并增加相关计数器。

for x in records:
    if x.date is None:
        missingValue += 1
    else:
        delta = x.date - date.today()
        if delta.days < 0:
            passed += 1
        if delta.days < 10:
            tenDays += 1
        if delta.days < 30:
            thirtyDays += 1

对于大约50,000个记录,这需要大约5-6秒,这比我想要的长,我试图减少这个,因为记录的数量可能会增加。 问题实际上围绕着日期时间差异的高效计算,并将结果天数分组,就好像有一个更好的方法通过Django查询或其他我无法找到的方法我可以尝试它

我已经在原始SQL中探索了DateAdd的使用,但似乎需要我查询每个日期范围的数据库,并且仍然会导致我需要遍历结果。

2 个答案:

答案 0 :(得分:1)

在优化性能之前,我会考虑批量执行。您最小的更改窗口似乎是1天。因此,通过过滤记录模型中的“更新”字段,您可以每小时(每个cron)调用一次:

from datetime import datetime, timedelta
records.objects.filter(updated__lt = datetime.now()-timedelta(days=1))[:2083]

并做你的操作。 请注意,您可以限制检索的记录数。因此,每小时您将获得2083(或5000)个记录,在一天中划分任务。您可以根据数据库中的记录数量(例如50000/24 = 2083)

来缩放此数字

此外,您的迁移可能希望反映出您想要在过去设置它,以便每个实时记录在开始时处理一次。

答案 1 :(得分:1)

使用SQL窗口COUNT

WITH cte AS (
     SELECT *,CASE WHEN DATEDIFF(DAY,GETDATE(),targetdate) <=0  THEN 0
                   WHEN DATEDIFF(DAY,GETDATE(),targetdate) <=10 THEN 10
                   WHEN DATEDIFF(DAY,GETDATE(),targetdate) <=30 THEN 30
                   ELSE 31 END AS grp
     FROM [record]   
     --WHERE targetdate > GETDATE() - 60  -- last 60 days
)
SELECT DISTINCT grp, COUNT(*) OVER(ORDER BY grp) AS running_count
FROM cte;

<强> Rextester Demo