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 不得加缓存)。
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Router } from 'express'
|
||||
import { setHttpCache } from '../../middleware/http-cache.js'
|
||||
import {
|
||||
approveAdminKuaishouIndustryRefund,
|
||||
checkAdminKuaishouIndustryVoucherAvailable,
|
||||
@@ -41,6 +42,7 @@ router.get(
|
||||
router.get(
|
||||
'/kuaishou-industry/shops',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
setHttpCache(300),
|
||||
createJsonHandler(() => listAdminKuaishouIndustryShops(), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '查询快手行业店铺失败',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Router } from 'express'
|
||||
import { setHttpCache } from '../../../middleware/http-cache.js'
|
||||
|
||||
import {
|
||||
deleteAdminWorkCategory,
|
||||
@@ -89,6 +90,8 @@ router.delete(
|
||||
router.get(
|
||||
'/worker-platform/categories',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
// 分类是低频配置:给浏览器 5 分钟本地缓存,避免每次刷新都发一次请求
|
||||
setHttpCache(300),
|
||||
createJsonHandler(() => listAdminWorkCategories(), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取接单分类失败',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Router } from 'express'
|
||||
import { setHttpCache } from '../../../middleware/http-cache.js'
|
||||
|
||||
import {
|
||||
acceptAdminWorkOrders,
|
||||
@@ -49,6 +50,7 @@ router.get(
|
||||
router.get(
|
||||
'/worker-platform/orders/mock/custom-shops',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
setHttpCache(300),
|
||||
createJsonHandler(() => ({ items: listAdminMockCustomShops() }), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取自定义店铺失败',
|
||||
|
||||
Reference in New Issue
Block a user