From 364911dc9e983abe7ae4b610386ba7d2c16c0a71 Mon Sep 17 00:00:00 2001 From: foxtacles Date: Tue, 5 May 2026 16:07:02 -0700 Subject: [PATCH] Index memory_completions(event_id, completed_at) for delete reconcile (#36) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The account-deletion reconcile in account.ts uses a correlated subquery to pick the latest-per-event row from memory_completions. Without an index whose leading column is event_id the inner subquery falls back to scanning sqlite_autoindex_memory_completions_1, making the reconcile O(rows^2) — observed cost in production was ~171k rows read for one deletion against ~407 rows. With this covering index the inner becomes a seek and the reconcile drops to ~rows*log(rows). --- server/migrations/0008_memory_completions_event_index.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 server/migrations/0008_memory_completions_event_index.sql diff --git a/server/migrations/0008_memory_completions_event_index.sql b/server/migrations/0008_memory_completions_event_index.sql new file mode 100644 index 0000000..c4bc07c --- /dev/null +++ b/server/migrations/0008_memory_completions_event_index.sql @@ -0,0 +1,7 @@ +-- Index on (event_id, completed_at DESC) for memory_completions. +-- Speeds up the per-event "latest row" lookup used by the account-deletion +-- reconcile in account.ts (the correlated subquery in +-- INSERT INTO memory_events ... SELECT ... WHERE id = (SELECT id FROM mc2 ...)). +-- Without this index that subquery is O(rows^2); with it, O(rows * log rows). +CREATE INDEX IF NOT EXISTS idx_memory_completions_event_completed + ON memory_completions(event_id, completed_at DESC);