Repository navigation
perf(host-core): replace session updated_at index with composite index - #1435
Conversation
The idx_sessions_updated index only covered updated_at DESC. Because session queries sort by updated_at DESC, id DESC, SQLite was forced to load all matching sessions into memory and perform a TEMP B-TREE sort, significantly harming performance. This introduces a migration (v21 to v22) to drop the single-column index and replace it with a composite idx_sessions_updated_id. Co-Authored-By: Claude Code <noreply@anthropic.com>
muzimu217
left a comment
There was a problem hiding this comment.
Verified the perf claim against today's main (6881a2bfd) — the principle is sound and the composite index matches the real query shapes:
- Hot session-list paths really do
ORDER BY s.updated_at DESC, s.id DESC(crates/host-core/src/plugin_sessions.rs:861-865,session_collaboration/projections.rs:274) — exactly whatidx_sessions_updated_id(updated_at DESC, id DESC)serves without a temp b-tree. This is where the reported latency comes from. crates/host-core/src/sessions.rs:1291orders byupdated_at DESCalone — still served by the new index as a prefix, so droppingidx_sessions_updatedis safe there.crates/host-core/src/session_search.rs:114usesupdated_at DESC, id ASC— the composite can't serve thatid ASCtiebreak, but the old single-column index didn't either; no regression.- Migration wiring is correct as far as I can read it: the v21→v22 step follows the v20→v21 pattern (backup + transaction + user_version bump), the legacy-path re-read of
migrated_versionafter v20→v21 keeps chained upgrades on the loop path, and updating thev20_database_migrates_...fixture to pre-create the old index name is the right call now that fresh schema creates the composite directly.
Two things standing between this and mergeable, both visible in CI:
cargo fmt --checkis the only Rust failure (the failed step is "Check formatting"; tests/lint themselves aren't the blocker) — the new test has trailing-whitespace blank lines.cargo fmtfixes it.- Base gate: needs a rebase onto latest
main.
One suggestion, not a blocker: add an EXPLAIN QUERY PLAN regression asserting the session-list query uses idx_sessions_updated_id without USE TEMP B-TREE FOR ORDER BY. That pins the actual invariant #1434 is about (query plan), not just the DDL — a future query reshuffle that silently reintroduces the memory sort would otherwise pass this test suite.
|
Update with local toolchain verification (rustup installed here, so we can now run the Rust gates directly):
So after |
The session index change must land against the current migration chain and project baseline.
The composite session index migration advances the database schema to version 22. Keep the fresh-database and legacy-upgrade assertions aligned so the host-core suite continues to cover current-schema startup. Document the session-list index and keep the migration Rust-formatted for the landing gate.
Fixes #1434
Motivation
When listing sessions, the
ORDER BY s.updated_at DESC, s.id DESCclause could not fully utilize the existingidx_sessions_updated(which only coversupdated_at DESC). This forces aTEMP B-TREEsort in SQLite memory.Changes
SCHEMA_VERSIONto 22idx_sessions_updatedwithidx_sessions_updated_id(updated_at DESC, id DESC)schema.rsand database startup routing inrepositories.rs🤖 Generated with Claude Code