Description
Store::list_audit_logs in crates/store/src/lib.rs supports an ILIKE '%' || $3 || '%' search over action and coalesce(target, ''). crates/store/migrations/0006_audit_logs.sql indexes (user_id, created_at DESC) and (user_id, category), but neither index can accelerate the ILIKE search — a leading-wildcard ILIKE can't use a plain B-tree index at all, so any search query today does a full per-user scan (bounded by user_id, but still a sequential filter over every one of that user's audit rows).
Requirements and Context
- Evaluate adding a
pg_trgm GIN trigram index on action (and possibly target) to accelerate the ILIKE '%...%' pattern, since this is the standard Postgres approach for substring search — this requires CREATE EXTENSION IF NOT EXISTS pg_trgm; in the migration (the repo already enables pgcrypto similarly in 0001_init.sql, so there is precedent for extension use).
- Attach
EXPLAIN ANALYZE output (before/after) in the PR description for a representative search query against a user with several thousand seeded audit rows, showing the plan shifts from a sequential/bitmap scan filtered in-memory to an index-assisted plan.
- If trigram indexing turns out not to meaningfully help at this table's expected scale (audit logs are typically modest per-user volumes), document that finding instead of forcing an index — this ticket's deliverable is the investigation and verified outcome, not a specific index by default.
Suggested Execution
Branch: perf/store/audit-log-search-index
Implement Changes
- Add
crates/store/migrations/0009_audit_log_trgm_index.sql (or the next free migration number) if the investigation supports it.
Test and Commit
- Existing
list_audit_logs tests (see the related search-filter testing issue) must continue to pass — this is a performance-only change with no query-result differences expected.
- Run
cargo test -p octo-store locally before committing.
Example Commit Message
perf(store): add a trigram index for audit-log search, or document why it isn't needed
list_audit_logs' ILIKE search couldn't be accelerated by the existing
B-tree indexes. Investigates and, where EXPLAIN ANALYZE confirms a real
benefit at realistic audit-log volumes, adds a pg_trgm GIN index; otherwise
documents the finding.
Guidelines
- Do not add the index speculatively without the EXPLAIN ANALYZE evidence in the PR description — this is explicitly an investigate-then-decide ticket, not a guaranteed-index ticket.
- Reference this issue with
Closes #<issue-number> in the PR description.
Description
Store::list_audit_logsincrates/store/src/lib.rssupports anILIKE '%' || $3 || '%'search overactionandcoalesce(target, '').crates/store/migrations/0006_audit_logs.sqlindexes(user_id, created_at DESC)and(user_id, category), but neither index can accelerate theILIKEsearch — a leading-wildcardILIKEcan't use a plain B-tree index at all, so any search query today does a full per-user scan (bounded byuser_id, but still a sequential filter over every one of that user's audit rows).Requirements and Context
pg_trgmGIN trigram index onaction(and possiblytarget) to accelerate theILIKE '%...%'pattern, since this is the standard Postgres approach for substring search — this requiresCREATE EXTENSION IF NOT EXISTS pg_trgm;in the migration (the repo already enablespgcryptosimilarly in0001_init.sql, so there is precedent for extension use).EXPLAIN ANALYZEoutput (before/after) in the PR description for a representative search query against a user with several thousand seeded audit rows, showing the plan shifts from a sequential/bitmap scan filtered in-memory to an index-assisted plan.Suggested Execution
Branch:
perf/store/audit-log-search-indexImplement Changes
crates/store/migrations/0009_audit_log_trgm_index.sql(or the next free migration number) if the investigation supports it.Test and Commit
list_audit_logstests (see the related search-filter testing issue) must continue to pass — this is a performance-only change with no query-result differences expected.cargo test -p octo-storelocally before committing.Example Commit Message
Guidelines
Closes #<issue-number>in the PR description.