perf: P1 性能优化批量修复 + kefu 视图拆分
P1 性能优化(避免循环内 N+1 / N 次 DB 查询): - shop_order_views._batch_images: 移除 ThreadPoolExecutor 掩盖的 N 次查询,改单次批量 + Python 侧分组 - product_query.DashouHuiyuanList: 5N 查询 -> 3 次批量预取 + 本地闭包判断 - roles.GetRolePermissionView / 用户列表: 循环内 RolePermission/Permission/UserRole/Role -> 批量 __in 预取 - guanli / zuzhang 杜次分红 4.2/4.3: 循环内 update_or_create + 单条 delete -> bulk_create + bulk_update + 批量 delete - admin_config QQ 群配置: 循环内 exists/first/save/create -> 批量预取 + bulk_create + bulk_update - jituan 服务层多处合并统计查询、批量预取 map - rank 多处循环 N+1 改批量预取 - backend 多处循环内 count/create 改批量 - config/orders/merchant_ops 多处循环 N+1 改批量预取 其他改动: - users/views/kefu.py 拆分为 kefu_base/kefu_dashou/kefu_orders/kefu_punishment/kefu_withdraw 5 个文件 - 删除遗留脚本 check_prod_uid.py / create_rbac_tables.sql
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import hmac
|
||||
import hmac
|
||||
import threading
|
||||
import traceback
|
||||
import uuid
|
||||
@@ -241,11 +241,16 @@ class GetProductTypeZoneView(APIView):
|
||||
return Response({'code': 400, 'msg': scope_err})
|
||||
|
||||
# 查询所有商品类型(含专区数量)
|
||||
# 一次性分组聚合所有类型的专区数量,避免循环内 N+1 count
|
||||
# 注:ShangpinZhuanqu.leixing_id 是 PositiveIntegerField(非 FK),无法用反向 annotate
|
||||
zone_count_rows = ShangpinZhuanqu.query.values('leixing_id').annotate(cnt=Count('id'))
|
||||
zone_count_map = {row['leixing_id']: row['cnt'] for row in zone_count_rows}
|
||||
|
||||
types = ShangpinLeixing.query.all().order_by('-paixu') # paixu 越大越靠前
|
||||
type_list = []
|
||||
for t in types:
|
||||
# 统计该类型下的专区数量
|
||||
zone_count = ShangpinZhuanqu.query.filter(leixing_id=t.id).count()
|
||||
# 从预聚合的 map 中取专区数量
|
||||
zone_count = zone_count_map.get(t.id, 0)
|
||||
type_list.append({
|
||||
'id': t.id,
|
||||
'jieshao': t.jieshao or '',
|
||||
@@ -531,10 +536,11 @@ class ModifyProductTypeZoneView(APIView):
|
||||
# 删除该类型下的所有专区
|
||||
zones = ShangpinZhuanqu.query.filter(leixing_id=type_id)
|
||||
if delete_products:
|
||||
# 删除专区下的所有商品
|
||||
for zone in zones:
|
||||
Shangpin.query.filter(zhuanqu_id=zone.id).delete()
|
||||
zones.delete()
|
||||
# 收集 zone_ids 后批量删除,避免循环内 N+1 delete
|
||||
zone_ids = list(zones.values_list('id', flat=True))
|
||||
if zone_ids:
|
||||
Shangpin.query.filter(zhuanqu_id__in=zone_ids).delete()
|
||||
ShangpinZhuanqu.query.filter(id__in=zone_ids).delete()
|
||||
# 删除直接关联该类型的商品
|
||||
Shangpin.query.filter(leixing_id=type_id).delete()
|
||||
else:
|
||||
@@ -928,7 +934,8 @@ class PopupNoticeModifyAPIView(APIView):
|
||||
if cascade:
|
||||
# 级联删除:使用事务保证原子性
|
||||
with transaction.atomic():
|
||||
popups = page.popups.all()
|
||||
# 预加载 images 关联,避免循环内 N+1 访问 related manager
|
||||
popups = page.popups.prefetch_related('images')
|
||||
for popup in popups:
|
||||
# 删除弹窗下的所有图片文件
|
||||
for img in popup.images.all():
|
||||
|
||||
Reference in New Issue
Block a user