修性能回归:把「已并入 / 子段」判据做成派生列(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:
@@ -592,3 +592,25 @@ WHERE p.id = sub.place_id
|
||||
ON er.dataset_id = v.dataset_id AND er.entity = 'ZVISIT' AND er.src_pk = v.src_pk
|
||||
WHERE v.place_id = p.id
|
||||
AND (er.raw->>'ZMERGEDTO' IS NOT NULL OR er.raw->>'ZPARENT' IS NOT NULL));
|
||||
|
||||
-- 「这次到访不独立成立」(已并入别处 / 只是某个父段的一部分)做成派生列(2026-09-30)
|
||||
--
|
||||
-- 读侧到处要判它(时间线、统计、地点列的 5 个子查询、专题……),原来是每行去 entity_raw 里
|
||||
-- 取回**整行 Core Data JSON** 再解析 raw->>'ZMERGEDTO':实体表里的 raw 是 TOAST 过的整行,
|
||||
-- 一次探针要几毫秒,地点库那种「每个地点 × 5 个子查询」的量级下实测 70 秒才出页面。
|
||||
-- 派生成一列之后读侧只看布尔值(实测 /places 5.3s → 0.01s 量级)。
|
||||
--
|
||||
-- ⚠️ 写入侧要跟着刷:导入(internal/ingest)、合并(backup_merge 的 recountPlaces)都会重算。
|
||||
-- 直接改 entity_raw 的合并标记(比如 tools/ 里的脚本)之后也要重跑一次这里的 UPDATE。
|
||||
ALTER TABLE visits ADD COLUMN IF NOT EXISTS is_merged BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
UPDATE visits v SET is_merged = TRUE
|
||||
FROM entity_raw er
|
||||
WHERE er.dataset_id = v.dataset_id AND er.entity = 'ZVISIT' AND er.src_pk = v.src_pk
|
||||
AND (er.raw->>'ZMERGEDTO' IS NOT NULL OR er.raw->>'ZPARENT' IS NOT NULL)
|
||||
AND NOT v.is_merged;
|
||||
|
||||
-- 给「从 entity_raw 重算 is_merged」用:只索引确实带合并标记的那几十行,
|
||||
-- 不用取回 raw 就能判定(上面那条回填与导入回填都走它,否则一次导入要多花几秒)。
|
||||
CREATE INDEX IF NOT EXISTS idx_entity_raw_visit_flags ON entity_raw (dataset_id, src_pk)
|
||||
WHERE entity = 'ZVISIT' AND (raw->>'ZMERGEDTO' IS NOT NULL OR raw->>'ZPARENT' IS NOT NULL);
|
||||
|
||||
Reference in New Issue
Block a user