Uh oh!
There was an error while loading. Please reload this page.
perf(database): index ProjectAlert.channelId so alert-channel deletes stop seq-scanning - #4554
Conversation
|
WalkthroughAdds an index on 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Why this change
Deleting a
ProjectAlertChannelfires the FK cascadeDELETE FROM ONLY "ProjectAlert" WHERE $1 = "channelId". That cascade is scan-shaped: with no index onchannelId, it reads the entireProjectAlerttable to find the few child rows belonging to the deleted channel. The parentDELETE ProjectAlertChanneldoes almost no work itself; its latency is dominated by this cascade.ProjectAlertis append-heavy and grows over time, so the scan cost only increases.Diagnosis
ProjectAlerthad no index onchannelId(onlypkey+ afriendlyIdunique). The cascade therefore did a full sequential scan of the whole table. The siblingProjectAlertStoragecascade on the same delete is index-backed and stays fast, which isolates the missing index as the cause.Change
Add
@@index([channelId])onProjectAlert, created withCREATE INDEX CONCURRENTLY IF NOT EXISTSsoprisma migrate deploystays safe on a live table.Benchmark (local, seeded)
Local Postgres seeded with 1,000,000
ProjectAlertrows across 50 channels (~20k rows per channel),EXPLAIN (ANALYZE, BUFFERS)on the cascade delete:ProjectAlert_channelId_fkeytriggerExpected impact
The cascade drops from a full-table sequential scan to a targeted index lookup. The win grows with the table: the more rows in
ProjectAlert, the more a scan costs and the more the index saves, so the benefit is larger than the seeded numbers above.Risks
ProjectAlertinsert; acceptable for a single-column index on a high-insert table, and it should be pre-created before the migration deploys (per the repo index rules).Follow-up
ProjectAlert's other cascade FK columns (projectId,environmentId,workerDeploymentId) are also unindexed, but their parents are soft-deleted rather than physically removed, so those cascades do not currently fire. Lower priority unless a hard-delete path is introduced.