我有一个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的使用,但似乎需要我查询每个日期范围的数据库,并且仍然会导致我需要遍历结果。
答案 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 强>