perf: 筛选统计去掉 JSON 兜底,并补上 orders 覆盖索引
去掉 work_orders 堆访问后,JOIN 会把 orders 整表扫进 Hash Right Join。 领取页在快照新鲜时不再打上游;快手出网统一 10 秒超时。倒计时改为自适应间隔。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -333,31 +333,26 @@ async function countWorkOrdersWithWhere(
|
||||
|
||||
/** 按筛选条件汇总工单,统计范围不受当前分页影响。 */
|
||||
/**
|
||||
* 统计用的「用户付款金额」表达式。
|
||||
* 统计用的「用户付款金额」。
|
||||
*
|
||||
* 优先读 083 迁移落下来的派生列 `source_order_amount_fen`(写入点:createWorkOrder /
|
||||
* updateWorkOrder,口径见 shared.ts 的 resolveSourceOrderAmountFen)。
|
||||
* **COALESCE 是短路求值**:列非空时后面两个分支根本不会被计算,所以命中列的行完全不碰
|
||||
* material_json——这正是把 2.8 秒的统计查询拉回毫秒级的关键(改造前每行要解析 1.2KB JSON,
|
||||
* 全表约 132MB,而且这个表达式在总付款与退款两处各求值一次)。
|
||||
* 只读 083 的派生列 `source_order_amount_fen`(写入点:createWorkOrder / updateWorkOrder,
|
||||
* 口径见 shared.ts 的 resolveSourceOrderAmountFen)。NULL 表示来源没给合法整数,
|
||||
* 回退 `orders.total_amount`,与 083 的列注释一致。
|
||||
*
|
||||
* 第二、三个分支是兜底,只为覆盖"写入点漏了"或迁移前的老行,保证口径永远正确:
|
||||
* 1) 派生列为 NULL 且 JSON 里有 15 位以内的合法整数 → 用 JSON 值;
|
||||
* 2) 否则回退 orders.total_amount(与改造前完全一致)。
|
||||
* 这里不能再写 `material_json`。执行器对 COALESCE 会短路,但规划器在规划期就记下列引用,
|
||||
* 只要 SQL 文本里出现这列,覆盖索引就做不了 index-only scan,9.7 万行宽表仍会被堆访问
|
||||
* (生产实测缓存未命中 248–545MB / 约 400ms)。漏写不在热路径上用 JSON 兜底,
|
||||
* 交给数据保留任务回填并打日志。
|
||||
*/
|
||||
const WORK_ORDER_PAYMENT_AMOUNT_SQL = `
|
||||
COALESCE(
|
||||
wo.source_order_amount_fen,
|
||||
CASE
|
||||
WHEN COALESCE(wo.material_json->'source'->>'orderAmountFen', '') ~ '^-?[0-9]{1,15}$'
|
||||
THEN (wo.material_json->'source'->>'orderAmountFen')::bigint
|
||||
END,
|
||||
COALESCE(o.total_amount, 0)
|
||||
)
|
||||
COALESCE(wo.source_order_amount_fen, o.total_amount, 0)
|
||||
`
|
||||
|
||||
export async function getWorkOrderStatistics(input: ListInput = {}): Promise<WorkOrderStatistics> {
|
||||
const { joins, whereClause, params } = buildWorkOrderWhere(input)
|
||||
// 仅勾「VIP 待补图」时才拼进 SQL。087 的覆盖索引故意不含 acceptance_json:
|
||||
// 这个筛选项会让统计回表变慢,是有意降级。不要把 acceptance_json 补进索引,
|
||||
// 否则默认统计(不勾这个筛选)会退回宽表堆访问。
|
||||
const vipEvidencePendingWhere = `
|
||||
wo.status = 'accepted'
|
||||
AND wo.acceptance_json->>'reviewMode' = 'vip_auto'
|
||||
|
||||
Reference in New Issue
Block a user