You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Django视图性能?复杂薪资计算视图加载超90秒

Django调度员工资计算视图性能优化方案

优先优化慢查询(见效最快)

  • 用django-debug-toolbar定位那两条耗时最长的查询,导出对应的SQL语句,检查是否存在全表扫描、嵌套子查询冗余的问题。
  • 给高频过滤/关联的字段加数据库索引:比如Load表的date字段、Dispatcher的location_id、BonusCustomer的dispatcher_id和customer_id,能大幅提升查询速度。
  • 把Python层面的计算逻辑尽量移到数据库端:
    • 基本工资的近2周平均周里程,用Django ORM的TruncWeek按周分组聚合,再取近2周的平均值,不要拉取所有里程数据到Python里计算。
    • 奖金的工单数量判断,用Case+When在数据库里直接完成“公司费率vs客户费率”的逻辑,一次性筛选出符合条件的工单数量,避免先拉所有工单再在Python里过滤。
  • 用select_related/prefetch_related提前关联依赖表:比如查询Dispatcher时,直接关联Location获取BaseRate;查询BonusCustomer时,批量预取关联的Load数据,避免N+1查询。

重构计算逻辑,降低视图复杂度

  • 不要把所有计算逻辑堆在视图里,抽成单独的服务类/函数(比如salary_calculator.py),视图只负责接收请求、调用计算函数、返回结果,这样代码更清晰,也方便单独测试优化。
  • 把重复使用的计算逻辑(比如获取公司近2周费率、客户上周费率)封装成模型方法或自定义管理器,避免重复写查询语句。

缓存:适合非实时计算的最优解

  • 薪资计算基于历史数据,不需要实时更新,直接用Django缓存框架缓存计算结果:
    • 单个调度员的薪资,缓存键设为dispatcher_salary_{dispatcher_id}_{today},缓存时长设为1天(每天凌晨更新一次即可)。
    • 如果是批量计算多个调度员,缓存整个结果集或者按地区分组缓存,避免重复计算。
  • 可以用Django的cache_page装饰器缓存整个视图的响应,但要注意如果不同用户看到的内容不同,需要结合用户ID或调度员ID做缓存键。

异步计算:适合批量/超复杂场景

  • 如果经过查询优化和缓存后,单次计算还是很慢(比如批量生成所有调度员的月度薪资),可以用Celery把计算任务放到后台异步执行:
    • 视图接收请求后立即返回“计算中,请稍后查看”的提示,后台任务完成后把结果存到数据库或缓存,用户刷新页面就能看到。
    • 单个调度员的薪资计算没必要用异步,缓存足够解决问题。

是否拆分视图?没必要

拆分视图会增加前端请求次数和后端维护成本,反而降低效率。应该把计算逻辑从视图中剥离,而不是拆分视图本身。

内容的提问来源于stack exchange,提问作者Valeriu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:27:00