-
perf(persona): 画像圈人筛选补 14 条偏索引 —— 生产实测 23.4s → 84ms · aef7f5b6
生产现象:召回池按「禁忌:手术禁忌」圈人,前端等 20+ 秒 GET /pac/v1/plans?view=pool&personaTags=contraindication:surgery 服务端复现:count 23,379ms + findMany 22,208ms(两句并发,墙钟 ≈23s)。 **不是禁忌特有** —— 测试服同口径按 rfm:重要价值 更慢,57s。14 个圈人维度全踩同一个坑, 禁忌只是这次先点到的那个。 根因:Prisma 把画像筛选编译成两层 EXISTS,最内层 persona_features.key = 'contraindication' AND (data #> '{domains}') @> '"surgery"' 而 persona_features 只有单列 key 索引,JSON 那半截没有索引可下推。 生产 EXPLAIN (ANALYZE, BUFFERS) 实测(7,657,944 行 / 5.4GB,堆 3.4GB): Index Scan using persona_features_key_idx actual time=3567..3954ms Index Cond: (key = 'contraindication') Filter: ((data #> '{domains}') @> '"surgery"') rows=2,156 Rows Removed by Filter: 188,054 ← 命中率 1.1% Buffers: shared read=162,830 ← 约 1.3GB 随机堆读 即为了捞 2,156 行,把该维度 190,210 行的 jsonb 全从磁盘搬了一遍。维度越大越惨: rfm / gender / lifecycle_stage 各 869,043 行,一次筛人搬 869k 行 data。 改动:每个可筛维度一条偏索引(WHERE key='<维度>'),表达式与 Prisma 生成的完全一致。 - 数组维度 7 条(array_contains → @>)→ GIN jsonb_path_ops - 标量维度 7 条(equals → =) → btree (表达式, persona_id) 第二列不是为了排序,是为了 index-only scan:内层 EXISTS 只 SELECT persona_id, 索引自带就不回堆。低选择性维度非它不可 —— 测试服实测 rfm 走上 btree 后 Bitmap Index Scan 只花 217ms,回堆 143,187 个块却花了 103s(work_mem 不够还退化成 lossy,Rows Removed by Index Recheck 1,564,553)。 Prisma schema 表达不了表达式/偏索引,只能落迁移 SQL;本地 migrate dev 会把它们报成 drift, 别按提示 reset(同类先例 20260727070000 / 20260727110000)。 persona-tag-filters.ts 加纪律注释:往 PERSONA_TAG_FILTER_DIMS 加维度必须同步补索引, 漏建就是 20 秒起步 —— 这次禁忌踩的正是这个。 上线(两台均已 CONCURRENTLY 手工建完,不锁表,业务无感;迁移全 IF NOT EXISTS 故 deploy 空跑): 生产 14 条 / 88s / 220MB,pg_index 无 invalid contraindication:surgery 23,379ms → 84ms(278×,1,347 单) contraindication:implant 842ms(25,900 单) rfm:important_value 1,558ms(61,300 单) treatment_history:implant_history 854ms(17,179 单) gender:female 2-4s (105,110 单) 测试服 14 条 / 238s / 195MB(盘慢,看倍数) rfm:important_value 57,299ms → 8,576ms contraindication:surgery 4,210ms → 344ms 剩下的耗时性质已经变了:不再是 JSON 过滤,而是结果集本身大(count(*) 要数完十万级 plan)。 gender 这类宽维度哪天嫌慢,方向是给 count 做近似/缓存,不是继续加索引。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>luoqi committed
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| asr-sensevoice | Loading commit data... | |
| pac-docs | Loading commit data... | |
| pac-service | Loading commit data... | |
| pac-web | Loading commit data... |