简体   繁体   English

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

[英]Django: how do you deal with queries that can not scale?

In my code, I have a few queries that are not scalable at all. 在我的代码中,我有一些根本无法扩展的查询。

For example, take a look at this code: 例如,看下面的代码:

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)

At the beginning, it perfectly worked. 刚开始时,它运行良好。 The problem is, when order amount increase, the performance seems to decreases in a linear way, which makes senses because all orders need to be tested each time. 问题是,当订单数量增加时,性能似乎呈线性下降,这是有道理的,因为每次都需要测试所有订单。 Having 1000 new orders every day, it's obvious my system will not be usable anymore in a few time! 每天有1000个新订单,很明显,我的系统将在短时间内无法使用!

Usually, how do you deal with this kind of problem in Django? 通常,您如何在Django中处理此类问题?

I mean, sometimes I can find a trick to write a better query, using Django ORM only. 我的意思是,有时我可以找到一个技巧,仅使用Django ORM编写更好的查询。 But sometimes, to get what I want, I seems to be forced to create my queryset this way, using Python and a for loop. 但是有时候,为了得到我想要的东西,我似乎不得不使用Python和for循环以这种方式创建查询集。

Please don't enumerate over .all() unless you absolutely have to. 除非绝对必要,否则请不要列举.all() It is more efficient to do filtering at the database side. 在数据库端进行过滤更有效。 Given localdate(..) does not do much, except extracting the date from a datetime , you can filter with: 给定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)

If localdate(..) is more advanced, you can still try to do most of the work at the database side. 如果localdate(..)更高级,您仍然可以尝试在数据库端完成大部分工作。 For example by filtering the queryset down to orders that are within for example 24 hours of the given date , and then do advanced filtering at the Python/Django side. 例如,通过将查询集过滤为给定date 24小时内的订单,然后在Python / Django端进行高级过滤。 But the idea is to do as much as possible at the database side (unless you make some exotic queries that do not scale well at the database, but that is quite rare). 但是,这样做的想法是在数据库端尽可能多地执行操作(除非您进行一些在数据库中无法很好扩展的奇异查询,但这很少见)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM