【发布时间】:2019-08-15 01:10:19
【问题描述】:
我是一个 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 个查询。
-
我应该尝试研究使用 select_related 和 prefetch 还是跳过所有这些并尝试编写一个 sql 查询来执行多个连接并以 json 格式一次获取所有数据?
当我传入单个对象(get 的结果)而不是序列化程序的查询集时,如何定义预取/select_related?
一些 db 实体之间没有链接,这意味着不是 fk 或多对多关系,只是持有一个与另一个有 id 的字段,但在数据库中没有强制执行这种关系?这对我来说会是个问题吗?这是否意味着我应该跳过 select_related 方法并编写一个客户 sql 用于获取?
您建议如何对这个噩梦般的查询进行性能调优?
【问题讨论】:
-
在您引用的特定情况下,您是一次只处理一个
Account(如代码所示)还是几个(重复get()查询)? -
@EndreBoth 一次一个帐户,有许多相关的嵌套模式
-
那么你必须有一个非常复杂的层次结构才能陷入困境 - 检查你是否真的需要预先嵌套所有的东西,或者你是否可以按需加载它们。
-
是的,我正在经历这个过程,但与此同时,我更愿意在我可以的地方进行连接...如何为 get 查询提供预取/选择相关的?因为它返回一个模型,而不是查询集?
-
如果您将
get替换为filter(...)[0],您最终会得到相同的对象,但您可以实现任何预取或预选。但这与 Jens 提出的方法没有太大区别。
标签: django performance django-models django-rest-framework query-performance