Django:您如何处理无法扩展的查询?

时间:2019-01-22 11:23:46

标签: python django django-models

在我的代码中,我有一些根本无法扩展的查询。

例如,看下面的代码:

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循环以这种方式创建查询集。

1 个答案:

答案 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端进行高级过滤。但是,这样做的想法是在数据库端尽可能多地执行操作(除非您进行一些在数据库上无法很好扩展的奇异查询,但这很少见。)