DRF视图性能优化求助:400条数据响应耗时2.8秒
DRF视图性能优化方案
针对你当前400条视频、6个分类却耗时2.8秒的问题,可从以下几个维度优化:
精准选择查询字段,剔除冗余数据
当前查询集加载了Videos的所有字段,但序列化仅用到id、description、title、url_video、url_image,illustration、video等未使用字段会占用额外内存与数据库传输资源。同时预取分类时,只需加载name字段即可,无需获取分类模型全量数据。修改查询集如下:from django.db.models import Prefetch class OfferListAPIView(generics.ListAPIView): queryset = Videos.objects.only('id', 'description', 'title', 'url_video', 'url_image').prefetch_related( Prefetch('category', queryset=CategoryVideos.objects.only('name')) ) serializer_class = VideoSerializer简化序列化逻辑,替换嵌套序列化器
原序列化器用嵌套的CategorySerializer2返回分类名称,可改用SlugRelatedField直接输出名称,避免嵌套序列化器的实例化开销:class VideoSerializer(serializers.ModelSerializer): category = serializers.SlugRelatedField(many=True, read_only=True, slug_field='name') class Meta: model = Videos fields = ["id", "description", "title", "url_video", "url_image", "category"] read_only = True添加分页,降低单次响应数据量
一次性返回400条数据会增加传输与解析耗时,给视图添加分页逻辑,让前端分批获取数据:from rest_framework.pagination import PageNumberPagination class StandardResultsSetPagination(PageNumberPagination): page_size = 20 page_size_query_param = 'page_size' max_page_size = 100 class OfferListAPIView(generics.ListAPIView): queryset = ... # 已优化的查询集 serializer_class = VideoSerializer pagination_class = StandardResultsSetPagination启用缓存,复用查询结果
如果视频与分类数据非实时更新,可对视图或查询结果添加缓存,避免重复查询数据库:from django.views.decorators.cache import cache_page from rest_framework.decorators import api_view @api_view(['GET']) @cache_page(60 * 15) # 缓存15分钟 def offer_list(request): queryset = Videos.objects.only('id', 'description', 'title', 'url_video', 'url_image').prefetch_related( Prefetch('category', queryset=CategoryVideos.objects.only('name')) ) serializer = VideoSerializer(queryset, many=True) return Response(serializer.data)检查数据库索引
确认多对多中间表的索引是否正常(Django默认会为多对多关系创建复合索引),可通过django-debug-toolbar查看生成的SQL语句,若存在慢查询,针对性补充索引。
内容的提问来源于stack exchange,提问作者mdc123
相关产品推荐
相关产品推荐

