在我的代码中,我有一些根本无法扩展的查询。
例如,看下面的代码:
class OrderQuerySet(query.QuerySet):
def for_day(self, day: date):
""" Return all orders that concerns the given service day """
day_order_pks = [order.pk for order in self.all()
if localdate(order.service.start) == day]
return self.filter(pk__in=day_order_pks)
在一开始,它就完美地工作了。 问题是,当订单数量增加时,性能似乎呈线性下降,这是有道理的,因为每次都需要测试所有订单。每天有1000个新订单,很明显,我的系统很快将无法使用!
通常,您如何在Django中处理此类问题?
我的意思是,有时我可以找到一个技巧,仅使用Django ORM编写更好的查询。但是有时候,为了得到我想要的东西,我似乎不得不使用Python和for循环以这种方式创建查询集。
答案 0 :(得分:2)
除非您绝对必须,否则请不要枚举.all()
。在数据库端进行过滤更有效。鉴于localdate(..)
除了从datetime
中提取日期之外没有什么作用,您可以使用以下方法进行过滤:
class OrderQuerySet(query.QuerySet):
def for_day(self, day: date):
""" Return all orders that concerns the given service day """
return self.filter(service__start__date=day)
如果localdate(..)
更高级,您仍然可以尝试在数据库端完成大部分工作。例如,通过将查询集过滤为给定date
的24小时内的订单,然后在Python / Django端进行高级过滤。但是,这样做的想法是在数据库端尽可能多地执行操作(除非您进行一些在数据库上无法很好扩展的奇异查询,但这很少见。)