代码之家  ›  专栏  ›  技术社区  ›  David Dahan

Django:你如何处理不能扩展的查询?

  •  1
  • David Dahan  · 技术社区  · 6 年前

    在我的代码中,我有一些根本不可伸缩的查询。

    例如,请看下面的代码:

    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-orm。但有时,为了得到我想要的,我似乎被迫用Python和for循环以这种方式创建我的查询集。

    1 回复  |  直到 6 年前
        1
  •  2
  •   willeM_ Van Onsem    6 年前

    拜托 不要 枚举 .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)

    如果 本地日期(…) 更高级的是,您仍然可以尝试在数据库端完成大部分工作。例如,通过将查询集过滤为在给定的24小时内的订单 date 然后在python/django端进行高级过滤。但其想法是尽可能多地在数据库端进行操作(除非您进行一些不适合在数据库中进行扩展的奇异查询,但这是非常罕见的)。