Files
order_site/apps/backend/src
yml2213 5092e88618 perf(admin): 打手等级筛选用 UNION 形式、概览加短缓存、静态配置接口加缓存头
三处都出自审计清单,改动互不重叠。

1) 打手等级筛选(生产实测 1119ms)
   原写法是对 worker_users 的两个相关 EXISTS(接单人 / 拼单参与人),规划器无法用它
   驱动索引,只能顺序扫完整张 work_orders。改成先把等级解析成打手 id
   (worker_users(level_id) 有索引,等级只有 6 个、解析出几百个 id),再走索引。
   注意:**不能**写成 `assigned_worker_id = ANY(...) OR id IN (...)` —— 实测 1852ms,
   比原写法还慢(OR 右支要逐行回表取 id)。用 UNION 形式:
     wo.id IN (SELECT id FROM work_orders WHERE assigned_worker_id = ANY(...) UNION
               SELECT work_order_id FROM work_order_shares WHERE worker_id = ANY(...) AND status != 'cancelled')
   实测 61ms(count),语义与原来完全一致(含"空数组=过滤掉全部")。
   三个入口 listWorkOrders / countWorkOrders / getWorkOrderStatistics 都先解析;
   未解析时保留原相关 EXISTS 兜底。

2) 平台概览短缓存(5 秒)
   一次并发 5 条 count(4 条打 work_orders,一条是运营态 CASE),而池只有 8 条连接,
   后台刷新时与其他请求互相争抢(抓包显示整批 9 个请求同时发出、它自身 167ms)。
   看板计数滞后几秒无感,用 WorkerListCache 缓存并合并并发。

3) 三个静态配置接口加 HTTP 缓存头(private, max-age=300)
   接单分类、快手行业店铺、自定义店铺此前没有任何 Cache-Control,每次刷新都真发一次
   请求(抓包里 4 个这类请求)。带 private 是因为这些是带鉴权的后台接口。
   **dev-mock/status 故意不加**:它是可切换状态,缓存会让"切了开关界面没变"。

验证:后端 547 项单测全绿(新增 4 项守卫,分别锁住 UNION 形式、三个入口都解析、
概览缓存、以及 dev-mock 不得加缓存)。
2026-10-01 15:36:46 +08:00
..
2026-08-23 15:01:11 +08:00
2026-08-16 17:27:12 +08:00
2026-08-23 12:54:38 +08:00