gpt4 book ai didi

django - 优化 Django Rest ORM 查询

转载 作者:行者123 更新时间:2023-12-02 20:03:16 26 4
gpt4 key购买 nike

我是一个 React 前端,django 后端(用作 REST 后端)。我继承了该应用程序,它使用许多模型和序列化加载所有用户数据。它加载速度非常慢。它使用过滤器来查询单个成员,然后将其传递给序列化器:

found_account = Accounts.objects.get(id='customer_id')
AccountDetailsSerializer(member, context={'request': request}).data

然后有很多各种各样的嵌套序列化器:

AccountDetailsSerializers(serializers.ModelSerializer):
Invoices = InvoiceSerializer(many=True)
Orders = OrderSerializer(many=True)
....

从日志来看,ORM 似乎发出了如此多的查询,这太疯狂了,对于某些端点,我们最终得到了 50 - 60 个查询。

  1. 我应该尝试使用 select_lated 和 prefetch,还是跳过所有这些,只尝试编写一个 sql 查询来执行多个联接并以 json 形式一次性获取所有数据?

  2. 当我传入单个对象(get 的结果)而不是查询集到序列化器时,如何定义预取/select_lated?

  3. 某些数据库实体之间没有链接,这意味着不是 fk 或多对关系,只是保存一个具有另一个 id 的字段,但数据库中并未强制执行该关系?这对我来说会是一个问题吗?这是否意味着我应该再次跳过 select_lated 方法并编写客户 sql 来获取?

  4. 您建议如何解决这个噩梦般的查询的性能调整?

最佳答案

我建议首先看看使用 prefetch_lated 会产生什么效果。它会对加载时间产生重大影响,并且实现起来相当简单。按照上面的例子,这样的事情就可以显着减少加载时间:

AccountDetailsSerializers(serializers.ModelSerializer):

class Meta:
model = AccountDetails
fields = (
'invoices',
'orders',
)

invoices = serializers.SerializerMethodField()
orders = serializers.SerializerMethodField()

def get_invoices(self, obj):
qs = obj.invoices.all()\
.prefetch_related('invoice_sub_object_1')\
.prefetch_related('invoice_sub_object_2')
return InvoiceSerializer(qs, many=True, read_only=True).data

def get_orders(self, obj):
qs = obj.orders.all()\
.prefetch_related('orders_sub_object_1')\
.prefetch_related('orders_sub_object_2')
return OrderSerializer(qs, many=True, read_only=True).data

至于您的架构问题,我认为还有很多其他因素会影响您是否应该重构代码库以及重构代码库的程度。但总的来说,如果您使用了 Django 和 DRF,如果您能够接受这些框架的惯用语和模式,而不是尝试通过自己的修复来接受它们,那么您将获得更好的开发人员体验。

关于django - 优化 Django Rest ORM 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55326865/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com