Skip to content

perf(sqlite): add idx_l0_user_agent_ts so L0 pagination stops rebuilding its sort - #1491

Open
Madin-H23 wants to merge 1 commit into
TencentCloud:feat/server_teamfrom
Madin-H23:fix/l0-user-agent-ts-index
Open

Madin-H23 wants to merge 1 commit into
TencentCloud:feat/server_teamfrom
Madin-H23:fix/l0-user-agent-ts-index

Conversation

@Madin-H23

Copy link
Copy Markdown

Summary

queryL0Paginated (v2 /conversation/query) filters sessions with (session_key = ? OR session_id = ?), which cannot drive ordered access by itself. The planner was picking (user_id, agent_id, session_id) as an equality scan and then rebuilding a TEMP B-TREE for every ORDER BY timestamp DESC LIMIT/OFFSET — so each page fetch and each count got slower as history grew.

  • Add idx_l0_user_agent_ts(user_id, agent_id, timestamp DESC): equality prefix + timestamp order lets the planner walk the index in ORDER BY order and stop at LIMIT+OFFSET — no per-page sort rebuild.
  • CREATE INDEX IF NOT EXISTS at init: idempotent, 23ms on a 3.2k-row DB.

Measured (standalone DB, 3,258 L0 rows)

Query Before After
paginated fetch + count (typical) 21.5 ms 5.9 ms
deep page (offset=3000) 40.6 ms 5.5 ms

Tests

  • New src/core/store/sqlite/l0-paginated.test.ts (4 cases) pins the query semantics that must not change with the index: session OR filtering (both session_key and session_id hit paths + non-match exclusion), new→old ordering, limit/offset pagination (disjoint pages, union = all, out-of-range offset = empty page with total intact), time-window filter, and index existence after init().
  • tsc --noEmit clean.

…ing its sort

queryL0Paginated filters sessions with (session_key = ? OR session_id = ?),
which cannot drive ordered access on its own. The planner was picking
(user_id, agent_id, session_id) as an equality scan and then rebuilding a
TEMP B-TREE for every ORDER BY timestamp DESC LIMIT/OFFSET — so each page
and each count got slower as history grew.

Add idx_l0_user_agent_ts(user_id, agent_id, timestamp DESC): equality
prefix + timestamp order lets the planner walk the index in ORDER BY
order and stop at LIMIT+OFFSET. Measured on a 3.2k-row standalone DB:
paginated fetch + count 21.5ms → 5.9ms; deep page (offset=3000)
40.6ms → 5.5ms; index build 23ms (IF NOT EXISTS, idempotent at init).

Also add l0-paginated.test.ts pinning the query semantics that must not
change with the index: session OR filtering (both key and id paths),
new→old ordering, limit/offset pagination (disjoint pages, union = all,
out-of-range offset = empty page with total intact), time-window filter,
and the index's existence after init.

Signed-off-by: Weijian He <230282609+Madin-H23@users.noreply.github.com>
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