Skip to content

The typed recompute plans its statements for the base it is given - #3

Merged
gedaiu merged 1 commit into
re-devfrom
perf/recompute-plans-per-base
Oct 18, 2026
Merged

gedaiu merged 1 commit into
re-devfrom
perf/recompute-plans-per-base

Conversation

@gedaiu

@gedaiu gedaiu commented Oct 18, 2026

Copy link
Copy Markdown

On Lore's deployment a materialize_typed job ran its source cleanup (DELETE FROM typed_fact_sources … NOT EXISTS (…), step 1 of materialize_in_tx) for over three hours on a base of about 438,000 facts and 200,000 typed-fact sources. It held the database at its 4-CPU limit, and a second recompute of the same base waited on the advisory lock behind it.

The statement is fast when planned for its base. On a copy of that base's tables (same rows, same indexes, work_mem 16MB):

Plan Time
Custom plan, the base's id known 2.2 s
Generic plan of the prepared statement cancelled at 10 min

sqlx prepares statements, and after a few runs on a connection Postgres switches to a generic plan. That plan can't see how many rows t.kb_id = $1 selects. It guesses about four statements and picks a nested-loop anti-join that rescans about 356,000 materialized rows for each of the base's 200,000 sources.

materialize_in_tx now starts with SET LOCAL plan_cache_mode = force_custom_plan. It is scoped to the transaction and covers both entry points, the worker's materialize and the job's try_materialize. The new test a_recompute_plans_its_statements_for_the_base_it_is_given checks the recompute's transaction plans that way, and fails without the change; a timing test would be flaky.

Upstream: proposed on deeplethe#1298, held until the maintainer agrees the shape. Not a decision record: it's a plan fix with no behaviour change.

🤖 Generated with Claude Code

… a generic plan cannot turn its source cleanup into hours.

Signed-off-by: Bogdan Szabo <bogdan@re-cinq.com>
(cherry picked from commit 02c10aa)
@gedaiu
gedaiu merged commit 52c8f38 into re-dev Oct 18, 2026
6 checks passed
gedaiu added a commit to re-cinq/lore that referenced this pull request Oct 18, 2026
…d by document) (#2810)

re.13 = re.12 + the typed recompute planned for its base (re-cinq/utopia#3, deeplethe/utopia#1298), an index on fact_evidence(document_id) (#5, fork migration 9000), the utopia:temporal review fixes (#4) and re-dev CI (#1). Apply with terraform -target='kubernetes_deployment_v1.utopia[0]'.
@gedaiu

gedaiu commented Oct 18, 2026

Copy link
Copy Markdown
Author

Upstream asked for a different shape, now deeplethe#1307: .persistent(false) on the whole-base statements plus s.kb_id = $1, instead of this SET LOCAL. When it merges and dev is synced into re-dev, this commit should be reverted in the same sync, so re-dev carries upstream's version only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant