使用Django,我有两个相关的模型。拨打第一个BaseObject
。第二个叫做BaseObjectObservation
,每6个小时左右我创建一个新的BaseObjectObservation
,它通过ForeignKey链接到BaseObject
,并且有另一个字段用于关于该对象的特定数据点那个时候,还有一个时间戳。
正如您所料,我一直感兴趣的是给定BaseObjectObservation
的“最新”BaseObject
。麻烦的是现在每个BaseObject
都有很多观察结果,即使有~500 BaseObject
s,加载一个包含所有BaseObject
s的页面,每个人的最新观察结果都非常慢。
有关如何加快检索最新观察的任何建议?
奖金问题:我也对过去24小时内每个物体的观察结果发生了变化感兴趣。以前我试过查询最近的观察和最接近24小时前的观察并计算差异;这太慢了。这里有什么建议吗?
答案 0 :(得分:1)
您可以执行以下操作:
class BaseObject(models.Model):
pass
class BaseObjectObservation(models.Model):
base_object = models.ForeignKey(BaseObject, related_name="observations")
last_modification = models.DateTimeField(auto_now=True)
latest = models.BooleanField(default=False)
def save(self, **kwargs)
if not self.pk:
# mark new instance as latest
self.latest = True
# Update previous observations
self.base_object.observations.update(latest=False)
super().save(**kwargs)
然后,如果您想获得基础对象的最新观察,您可以这样做:
BaseObjectObservation.objects.filter(latest=True).select_related('base_object')
select_related
子句将为您节省500个查询,因为它将在观察时获取基础对象。
由于您在单个查询中执行所有操作,因此性能应该更好。但是,可能存在一些最干净的解决方案,而无需在每个实例上存储布尔值。
对于你的奖金问题,你可能会得到some inspiration here:
import datetime
from django.utils import timezone
24_hours_ago = timezone.now() - datetime.timedelta(hours=24)
current_observation = base_object.observations.get(latest=True)
closest_observation_greater = base_object.observations.filter(creation_date__gt=24_hours_ago).first()
closest_observation_lower = base_object.observations.filter(creation_date__lte=24_hours_ago).first()
if closest_observation_greater - target > target - closest_observation_lower:
return closest_observation_lower
else:
return closest_observation_greater
然而,对于每个观察,仍然有两个查询。你可以优化它,但你也可以减少它 每页显示的元素数。你真的需要在同一页面上显示500个元素吗?