backend/sinks/storage.py creates thirteen tables and not one index. Every post-session query — reconstructing a ride, pulling a day of rankings, auditing signals — is a full table scan, and these tables grow by thousands of rows per session.
What to do
Add indexes in the existing additive-migration style (the _migrate_* methods show the pattern — CREATE INDEX IF NOT EXISTS, safe to run on an existing database):
signals(ts), signals(underlying, ts)
rankings(ts), rankings(underlying, ts)
oneway_movers(underlying, entry_ts), oneway_movers(ts)
- whatever the other boards are actually queried by
Acceptance
Notes
Measure, do not guess — an index that is never used still costs write time. Say which queries you optimised for.
backend/sinks/storage.pycreates thirteen tables and not one index. Every post-session query — reconstructing a ride, pulling a day of rankings, auditing signals — is a full table scan, and these tables grow by thousands of rows per session.What to do
Add indexes in the existing additive-migration style (the
_migrate_*methods show the pattern —CREATE INDEX IF NOT EXISTS, safe to run on an existing database):signals(ts),signals(underlying, ts)rankings(ts),rankings(underlying, ts)oneway_movers(underlying, entry_ts),oneway_movers(ts)Acceptance
EXPLAIN QUERY PLANbefore/after in the PR for at least one queryNotes
Measure, do not guess — an index that is never used still costs write time. Say which queries you optimised for.