perf(db): add hot-path indexes for recovery crons, Loom imports and storage listings - #2213
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three additive indexes plus a one-line predicate change, driven by PlanetScale Insights for
cap/cap-production/mainand verified withEXPLAINon a branch restored from today's backup.What changed
videos (isScreenshot, transcriptionStatus, createdAt): the two stalled-pipeline recovery crons inapps/web/lib/video-pipeline-recovery.tsfull-scannedvideosevery run (Insights: 22.6M + 22.6M rows read over 96 runs each, p99 197ms / 240ms). After: index range scan estimated at 735 / 3,355 rows instead of 215k.imported_videos (id): everyimported_videos.id = ?lookup was a table scan (no index onid). Video deletion runsDELETE ... WHERE id = ?inside a transaction, which under REPEATABLE READ next-key-locks every scanned row, so a delete could block concurrent Loom imports. The Loom recovery join also did a 304-row PK range per candidate. After: single-row covering lookup.storage_objects (integrationId, objectKey(191))+listObjectsByPrefixnow addsobjectKey LIKE prefix%alongside the existingBINARY objectKey LIKE prefix%. The collation-aware predicate is a strict superset of the binary one, so results are unchanged, but it lets MySQL range-scan the new index. Before: every listing read all objects for the integration (Insights: 9.8M rows over 1,229 runs, p99 628ms; the largest integration has 278k objects). After: range scan on the prefix for typicalowner/video/listings; large HLS-segment prefixes keep today's plan.Validation
EXPLAINon the restored branch for the three target queries and for the hot dashboard/list queries on the same tables (caps list, user cap count, storage hash/status lookups, notifications list): target plans switched to the new indexes, every other plan unchanged.pnpm db:generate;tsc --noEmitclean for@cap/databaseand@cap/web-backend; Biome clean.Greptile Summary
The PR adds three database indexes for recovery, imported-video, and storage-listing access paths while preserving case-sensitive storage-prefix semantics.
Confidence Score: 5/5
The PR appears safe to merge with no actionable correctness or security issues identified.
The added indexes are compatible with the repository’s database targets and migration chain, while the storage query retains its original binary filtering and pagination semantics.
Important Files Changed
Reviews (1): Last reviewed commit: "perf(storage): let prefix listings use t..." | Re-trigger Greptile
Context used: