如何诊断Django REST接口渲染速度远慢于本地测试的问题
排查步骤和解决方案
- 优先解决N+1查询问题
你当前的查询语句没有提前加载关联数据,序列化时访问customer(外键)、resources和rrule(多对多)字段时,每条Event都会单独发起3次数据库查询,100条数据就会产生300+次额外查询,这是序列化耗时高的核心原因。
将查询语句修改为:
events = Event.objects.filter(client=client, start__gt=start, end__lt=end).select_related('customer').prefetch_related('resources', 'rrule')
修改后再跑本地测试,序列化耗时大概率会降到100ms以内,接口耗时也会同步下降。
排查Debug模式的额外开销
你的本地测试脚本没有走Django完整请求链路,不会触发Debug模式的额外逻辑:Debug模式开启时,Django会记录所有执行的SQL、做字段校验、加载调试面板资源,几百条SQL产生的日志和计算开销很容易堆到几十秒。
把项目配置里的DEBUG改为False,重启服务后再用Insomnia测试,基本能排除这部分开销的影响。在视图内打点定位耗时环节
在接口视图的四个节点加时间打印,直接和本地测试的耗时做对比,精准定位慢的环节:
import time def your_event_view(request): t1 = time.time() # 你的查询逻辑 t2 = time.time() # 你的序列化逻辑 t3 = time.time() # 构造返回响应 t4 = time.time() print(f"查询耗时:{t2-t1}, 序列化耗时:{t3-t2}, 响应构造耗时:{t4-t3}") return response
如果查询+序列化的耗时和本地测试接近,额外耗时都在响应构造阶段,就检查是不是有全局的响应钩子、日志打印、响应压缩等逻辑拖慢了速度:不少项目会配置全量响应体日志打印,大体积JSON的序列化、写入磁盘的开销非常高。
- 验证序列化外的逻辑影响
直接在视图里返回你本地测试预先生成的JSON字符串,跳过查询、序列化步骤,看接口耗时是不是降到100ms以内:如果是,就确认问题完全出在查询和序列化环节,和认证、中间件无关;如果还是很慢,就检查是不是有接口层面的权限、限流、或者第三方中间件逻辑在遍历处理返回数据。
内容的提问来源于stack exchange,提问作者PoDuck
相关产品推荐
相关产品推荐

