perf: 筛选统计去掉 JSON 兜底,并补上 orders 覆盖索引
去掉 work_orders 堆访问后,JOIN 会把 orders 整表扫进 Hash Right Join。 领取页在快照新鲜时不再打上游;快手出网统一 10 秒超时。倒计时改为自适应间隔。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
-- 087_work_order_statistics_cover_index.sql —— 筛选统计的覆盖索引(085 的超集 + orders 窄列)。
|
||||
--
|
||||
-- 统计在 SUM 付款金额,085 只覆盖了运营态 CASE 的三列,金额表达式此前还引用
|
||||
-- material_json,规划器因此无法 index-only scan(缓存未命中实测 248–545MB)。
|
||||
-- 金额已改为只读 source_order_amount_fen / orders.total_amount。
|
||||
--
|
||||
-- 生产同一会话对比(唯一变量是表达式,不勾 VIP 待补图):
|
||||
-- 旧(含 JSON) work_orders Parallel Seq Scan,合计 550MB / 615ms
|
||||
-- 只加 work_orders 索引 work_orders Index Only Scan 56ms,
|
||||
-- 但 LEFT JOIN orders 变成 Hash Right Join,
|
||||
-- 26.5 万行 orders 整表 Seq Scan 235MB,合计 487ms
|
||||
-- 再加下面这条 orders 索引 两侧都是 Index Only Scan,合计 48MB / 317ms
|
||||
-- 所以 orders 索引必须跟这批一起建。生产上已并发建好,IF NOT EXISTS 在线上是 no-op;
|
||||
-- 不写进迁移的话,新环境会退回 orders 全表扫。
|
||||
--
|
||||
-- idx_orders_statistics_cover 与 orders_pkey 同键,只多 3 个 INCLUDE 列(约 10MB)。
|
||||
-- 彻底去重要重建 PRIMARY KEY (id) INCLUDE (...),会锁 443MB 的 orders,留维护窗口。
|
||||
-- 现在先接受这条重复索引。
|
||||
--
|
||||
-- 验收(真实 service 路径的 EXPLAIN (ANALYZE, BUFFERS),不勾 VIP 待补图):
|
||||
-- 1. 两侧都是 Index Only Scan。Heap Fetches 不可能为 0:VACUUM ANALYZE 之后
|
||||
-- 仍有约 1.7%(1,616 / 1,635)来自刚写入、可见性映射还没覆盖的行。
|
||||
-- 判据是低于 5%,或绝对数不超过数千。明显更高时再 VACUUM (ANALYZE)。
|
||||
-- 2. 单次耗时低于 500ms 慢查询线即可。实测约 317ms 是 CPU
|
||||
-- (约 9.7 万行两次 hash join + CASE 聚合),再往下压靠预聚合,不靠索引。
|
||||
--
|
||||
-- 故意不含 acceptance_json:勾「VIP 待补图」时统计会回表,这是有意降级。
|
||||
-- 把该列补进 INCLUDE 会让默认统计重新读宽表。
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_work_orders_statistics_cover
|
||||
ON work_orders (id)
|
||||
INCLUDE (
|
||||
status,
|
||||
sharing_enabled,
|
||||
sharing_total_quantity,
|
||||
source_order_amount_fen,
|
||||
reward_amount,
|
||||
order_id
|
||||
);
|
||||
|
||||
-- 见文件头:挡住 orders 被当成 Hash Right Join 的 build 侧整表扫。
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_statistics_cover
|
||||
ON orders (id)
|
||||
INCLUDE (pay_status, order_status, total_amount);
|
||||
|
||||
DROP INDEX IF EXISTS idx_work_orders_operational_status_cover;
|
||||
Reference in New Issue
Block a user