Django3.2中10万行级QuerySet高效转JSON接口响应的优化咨询
适配Django 3.2的高性能QuerySet转JSON方案
方案1:替换Pandas为高效JSON序列化库(改动最小,性能提升最明显)
核心逻辑:直接序列化values()返回的字典迭代器,完全砍掉构造DataFrame的2秒开销,使用高性能JSON库完成序列化,10万行数据整体序列化耗时可控制在200ms以内。
代码实现(最高性能版本)
需要先安装Rust开发的高性能JSON库orjson,序列化速度是标准json库、pandas to_json的5~10倍:
import orjson from django.http import HttpResponse from rest_framework import status @api_view(['POST']) def retrieve_signal_asset_weight_ts_by_signal(request): # 此处为根据请求获取item.id、start_date、end_date、columns_required的原有逻辑 qs = Sample.objects.filter( data_date__range=[start_date, end_date], item__id = item.id ).values(*columns_required) # 直接序列化查询结果,无需转list、无需经过DataFrame json_bytes = orjson.dumps(list(qs), option=orjson.OPT_UTC_Z | orjson.OPT_PASSTHROUGH_DATETIME) return HttpResponse(json_bytes, content_type='application/json', status=status.HTTP_200_OK)
无第三方依赖版本
如果不想引入额外依赖,可直接使用Django内置JsonResponse,性能比原Pandas方案快1倍左右:
from django.http import JsonResponse from rest_framework import status @api_view(['POST']) def retrieve_signal_asset_weight_ts_by_signal(request): # 原有逻辑不变 qs = Sample.objects.filter( data_date__range=[start_date, end_date], item__id = item.id ).values(*columns_required) return JsonResponse(list(qs), safe=False, status=status.HTTP_200_OK)
方案2:流式响应(内存占用更低,适合更大数据量场景)
如果后续数据量持续上涨,担心一次性加载10万行数据到内存导致OOM,可使用流式响应边生成边返回,内存占用稳定在KB级别,整体耗时和方案1基本持平:
import orjson from django.http import StreamingHttpResponse from rest_framework import status def json_streaming_generator(qs): yield b'[' first = True # 用iterator()避免把所有查询结果一次性加载到内存 for item in qs.iterator(): if not first: yield b',' yield orjson.dumps(item) first = False yield b']' @api_view(['POST']) def retrieve_signal_asset_weight_ts_by_signal(request): # 原有逻辑不变 qs = Sample.objects.filter( data_date__range=[start_date, end_date], item__id = item.id ).values(*columns_required) return StreamingHttpResponse( json_streaming_generator(qs), content_type='application/json', status=status.HTTP_200_OK )
优化小贴士
- 不要使用DRF默认的
Response处理10万行级别的数据,DRF内置渲染器会做额外的格式校验和转换,开销比直接返回HttpResponse高30%以上。 - 如果返回字段包含日期、Decimal等特殊类型,
orjson可通过参数直接支持序列化,无需自定义编码器。
内容的提问来源于stack exchange,提问作者Shubham Periwal
相关产品推荐
相关产品推荐

