Skip to content

fix(score-sets): index functional classification variant fk to unblock score set deletion - #874

Open
bencap wants to merge 1 commit into
release-2026.3.0from
bugfix/bencap/677/score-set-deletion-often-fails
Open

bencap wants to merge 1 commit into
release-2026.3.0from
bugfix/bencap/677/score-set-deletion-often-fails

Conversation

@bencap

@bencap bencap commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes #677.

score_calibration_functional_classification_variants carries variant_id only as the trailing column of its composite primary key (functional_classification_id, variant_id). Postgres has no index it can use to check that FK when a Variant row is deleted, so it sequentially scans the whole table once per variant — and that table is global, growing with every calibration ever created across MaveDB. Deleting a score set cascades to deleting each of its variants synchronously in the request, so for any score set with a nontrivial number of variants this dominates the delete and is slow enough to time out, non-deterministically depending on how large the association table has grown.

Confirmed with EXPLAIN against a synthetic 200k-row association table: the FK check plan flips from Seq Scan to Index Scan, and deleting 500 variants drops from ~2.6s to ~2.4ms.

The migration builds the index CONCURRENTLY, outside a transaction, since the table may already be large enough in production that a blocking build would itself be disruptive.

…k score set deletion

Deleting a score set cascades through SQLAlchemy to delete each of its variants, and
Postgres checks every foreign key into variants.id to enforce referential integrity on
each one. score_calibration_functional_classification_variants carries variant_id only
as the trailing column of its composite primary key (functional_classification_id,
variant_id), so that check has no index it can use and instead sequentially scans the
whole table once per variant being deleted. The table is global, growing with every
calibration ever created across MaveDB, so the cost compounds with both the deleted
score set's variant count and the table's total size.

This is the mechanism behind #677 ("unpublished score set deletion often fails"):
deletion runs synchronously in the request, and for any score set with a nontrivial
number of variants the per-variant sequential scan is slow enough to time out,
non-deterministically depending on how large the association table has grown. Confirmed
with EXPLAIN against a synthetic 200k-row table: the FK check plan flips from Seq Scan to
Index Scan, and deleting 500 variants drops from ~2.6s to ~2.4ms.

The migration builds the index CONCURRENTLY, outside a transaction, since the table may
already be large enough in production that a blocking build would itself be disruptive.
@bencap bencap linked an issue Sep 21, 2026 that may be closed by this pull request
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 35640332294

Warning

No base build found for commit f65ac35 on release-2026.3.0.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 88.971%

Details

  • Patch coverage: 1 of 1 lines across 1 file are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 15695
Covered Lines: 13964
Line Coverage: 88.97%
Coverage Strength: 0.89 hits per line

💛 - Coveralls

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.

Unpublished score set deletion often fails.

2 participants