我正在尝试优化数据库查询,prefetch_related但没有成功。
models.py
class Order(models.Model):
# some fields ...
@property
def last_operation(self) -> Optional['OrderOperation']:
try:
return self.orderoperation_set.latest()
except OrderOperation.DoesNotExist:
return None
@property
def total(self) -> Optional[Decimal]:
last_operation = self.last_operation
return last_operation.total if last_operation else None
class OrderOperation(TimeStampable, models.Model):
order = models.ForeignKey(Order)
total = DecimalField(max_digits=9, decimal_places=2)
运行一个shell,我可以看到问题所在:
orders = Order.objects.prefetch_related('orderoperation_set') # There are 1000 orders
result = sum([order.total for order in orders])
len(connection.queries)
>>> 1003
我们可以看到,每个查询有一个查询order.total,因此有1000个查询,这使整个请求非常糟糕,性能与订单数成线性关系。
为了理解为什么会这样,我在prefetch_related Django doc中找到了这个:
请记住,与QuerySet一样,任何暗示不同数据库查询的后续链接方法都将忽略先前缓存的结果,并使用新的数据库查询来检索数据。
因此,latest()每次调用都运行一个新查询似乎很正常。
在这种情况下,您将如何提高性能?(而不是N进行一些查询,其中N是订单数)。
慕尼黑8549860
手掌心
相关分类