环境:
Django=="2.2"
Python=="3.6.8"
debug_toolbar=="1.11"
rest_framework=="3.8.2"背景:
在从基于函数的DRF端点切换到基于类的视图/视图集时,我发现基于类的视图在没有嵌套关系的情况下表现得稍微好一些,对于嵌套关系则要差得多。
伪码模型上下文:
Creator:
ForeignKey.Shipments[]
Unit:
ForeignKey.Shipments[]
Shipment:
ForeignKey.Addresses[]
ForeignKey.Creator
ForeignKey.Unit
Address:
Street
City
State值得注意的序列化器上下文:
Unit:
Meta:
Depth = 1
Creator:
Meta:
Depth = Infinite当将上述结构的视图集与等效的@apiview进行比较时,我发现:
/addresses在SQL (0.9x)上的表现略好一些,其CPU开销为1.1x (预期)/creators在SQL (1.1x)上的表现略差,3.9xCPU开销(预期)/creators/1在SQL (0.9x)上的性能略好一些,3.4xcpu开销(意外)/creators/1在significant (3.3x)上的性能要差得多,CPU开销为5.9xCPU(意外)/units/1性能要差得多,CPU开销高达7.9xCPU(非常出乎意料)get_queryset的使用(非常出乎意料)。对@apiview检索的分解
(240 queries including 235 similar and 120 duplicates)
对viewsets.ReadOnlyModelViewSet检索的分解
(208 queries including 200 similar and 78 duplicates )
对viewsets.ModelViewSet检索的分解
(803 queries including 801 similar and 801 duplicates )
所有这些似乎都是不直观的。
两种类型的端点如何能够使用完全相同的序列化程序来执行如此不同的操作?
与基于函数的视图相比,Classviews和Viewset似乎会带来大量CPU和SQL性能的影响,在这些性能方面,我无法找到真正的原因涉及到外键。
我预计N+1查询的性能会很差,但我不希望它们执行更糟糕的,这取决于DRF端点的哪种样式。
有理由解释为什么会这样吗?
发布于 2019-06-06 18:08:41
这里的统计数据是一个错误的名称,这是因为DRF可浏览API对端点接受的每个方法执行额外的请求。
相应地,如果仅以1倍的引用速度执行GET,则由于执行3项额外请求,带有GET、PUT、修补程序、DELETE的端点执行速度似乎慢了4倍。
当一个端点上有多个请求方法可用时,DRF的可浏览API掩盖了真正的速度/查询数,为了查看端点的实际性能,您应该通过编程方式或使用?format=json来请求它。
当我通过分析发现权限类被击中6次时,我发现了这一点:
发布于 2019-06-05 21:33:29
看看这个答案,Optimizing database queries in Django REST framework。DRf不会自动优化您的查询,您仍然需要自己进行优化。
如果你想提高一点性能,看看这个应用程序https://github.com/K0Te/drf-serializer-cache。
https://stackoverflow.com/questions/56468148
复制相似问题