Skip to content

perf(db): add RLS composite index, aggregate helper, and chunk tuning - #62

Merged
cchwala merged 1 commit into
mainfrom
perf/db-improvements-batch
Jul 25, 2026
Merged

perf(db): add RLS composite index, aggregate helper, and chunk tuning#62
cchwala merged 1 commit into
mainfrom
perf/db-improvements-batch

Conversation

@cchwala

@cchwala cchwala commented Jul 25, 2026

Copy link
Copy Markdown
Member

Adds four database performance migrations, extracted and genericized from production learnings, that improve query performance for multi-tenant RLS-filtered access patterns on cml_data:

  • 010: composite index (user_id, cml_id, time DESC) so RLS-filtered queries can use a single index scan instead of scanning all users' data or requiring extra heap lookups.
  • 011: get_cml_aggregates() SECURITY DEFINER helper function for fast RLS-safe aggregated queries (e.g. from Grafana), avoiding security-barrier view overhead.
  • 012: reduce cml_data chunk_time_interval to 1 day and re-point the compression policy's compress_after to 1 day, bounding the size of the always-uncompressed open chunk for large tenants.
  • 013: covering index (INCLUDE sublink_id, rsl, tsl) on cml_data so open-chunk per-CML raw queries can be satisfied via index-only scan.

Each migration includes measured performance rationale in its header comment. All are additive/non-destructive and safe to apply independently in numeric order after migrations 001-009.

Adds four database performance migrations, extracted and genericized
from production learnings, that improve query performance for
multi-tenant RLS-filtered access patterns on cml_data:

- 010: composite index (user_id, cml_id, time DESC) so RLS-filtered
  queries can use a single index scan instead of scanning all users'
  data or requiring extra heap lookups.
- 011: get_cml_aggregates() SECURITY DEFINER helper function for fast
  RLS-safe aggregated queries (e.g. from Grafana), avoiding
  security-barrier view overhead.
- 012: reduce cml_data chunk_time_interval to 1 day and re-point the
  compression policy's compress_after to 1 day, bounding the size of
  the always-uncompressed open chunk for large tenants.
- 013: covering index (INCLUDE sublink_id, rsl, tsl) on cml_data so
  open-chunk per-CML raw queries can be satisfied via index-only scan.

Each migration includes measured performance rationale in its header
comment. All are additive/non-destructive and safe to apply
independently in numeric order after migrations 001-009.
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.59%. Comparing base (ca55ee2) to head (588e57f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #62      +/-   ##
==========================================
+ Coverage   86.10%   87.59%   +1.48%     
==========================================
  Files          39       35       -4     
  Lines        3418     3038     -380     
==========================================
- Hits         2943     2661     -282     
+ Misses        475      377      -98     
Flag Coverage Δ
mno_simulator 86.12% <ø> (ø)
parser 92.00% <ø> (ø)
scripts ?
webserver 73.78% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cchwala
cchwala merged commit 5ac61eb into main Jul 25, 2026
7 checks passed
cchwala added a commit that referenced this pull request Jul 25, 2026
A fresh DB (docker compose up with an empty volume) only runs
init.sql; migration files under database/migrations/ are only for
upgrading already-running deployments. init.sql was not updated when
migrations 010-013 were merged (#62), so a fresh install was missing:

- idx_cml_data_user_cml_time composite index (010)
- get_cml_aggregates() RLS-safe aggregation helper (011)
- 1-day chunk_time_interval + matching compress_after (012)
- idx_cml_data_covering covering index (013)

Verified by initializing a throwaway container from a clean volume
and confirming the resulting schema matches (index definitions,
chunk interval, compression policy config, and function signature).
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