修性能回归:把「已并入 / 子段」判据做成派生列(visits.is_merged)

昨天给「已并入 / 子段」做的收口写成每行去 entity_raw 判
`raw->>'ZMERGEDTO' IS NOT NULL OR raw->>'ZPARENT' IS NOT NULL`,而 entity_raw.raw 是
**TOAST 过的整行 Core Data JSON**:一次探针要取回并解析整行。地点库「每个地点 × 5 个子查询」
的量级下 —— 实测 /places 70.1 秒、首页 43.6 秒才出页面(而库里没有任何一条 SQL 超过 1 秒:
时间全花在成千上万次「取整行再解析」上,进程 CPU 只用了 3s/135s)。

这批「渲染若干页面」的布局用例因此从 20 秒涨到 226~309 秒,整套验收从 6 分钟变 20+ 分钟。

- schema.sql:加派生列 visits.is_merged + 回填 + 给回填用的部分索引
  (只索引确实带合并标记的那几十行,不用取回 raw)。
- stats.SoloVisitSQL 改成读这一列(判据仍然只此一份,读侧全部经由它)。
- 写入侧跟着刷:ingest 在 insertEntityRaw 之后、backup_merge 的 recountPlaces 里,
  共用 stats.RefreshMergedFlagsSQL。
- 直接改留档里的合并标记(工具脚本 / 用例)之后也要刷一次,schema.sql 与函数注释都写明了。

实测:/places 70084ms → 206ms,/ 43633ms → 698ms(比「关掉判据」的对照还快)。
新增 page_render_budget_test.go:给 7 个关键页卡 10 秒上限的灾难探测器
(功能全对、只是慢的那种退化,之前没有任何用例会红)。
This commit is contained in:
tamakyi
2026-09-30 16:18:52 +08:00
parent 5b8699a03a
commit c9ebb3aebd
7 changed files with 103 additions and 8 deletions
+5 -1
View File
@@ -93,12 +93,16 @@ func TestHiddenVisitStaysInExportButLeavesReads(t *testing.T) {
t.Fatalf("标记前 ZMERGEDTO 就不该有值,实际 %v", merged.Int64)
}
// 标记成「已并入 #target」
// 标记成「已并入 #target」。读侧判据取的是派生列 visits.is_merged,
// 所以直接改留档之后必须按生产路径刷一次(导入 / 合并也是这么刷的)。
if _, err := pg.ExecContext(ctx, `UPDATE entity_raw
SET raw = jsonb_set(raw, '{ZMERGEDTO}', to_jsonb($3::int), true)
WHERE dataset_id=$1 AND entity='ZVISIT' AND src_pk=$2`, dsID, victim, target); err != nil {
t.Fatalf("标记失败: %v", err)
}
if _, err := pg.ExecContext(ctx, stats.RefreshMergedFlagsSQL, dsID); err != nil {
t.Fatalf("刷新合并标记失败: %v", err)
}
// 1) 访客侧:时间线少了一条,且被标记的那条不再出现
rows, totalAfter, err := srv.q.Visits(ctx, flt, 5, 0, "desc")