Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 12 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
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 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.
attachment_idis a string column, butAttachOneOrMany::addConstraints()binds the parent key as an integer, and eager loading inlines integer keys through Laravel'swhereIntegerInRaw()(attachment_id in (1, 2, 3)). When MySQL compares a string column with a number, it converts every row's value, so it can't useattachment_id_index. It falls back to theattachment_typeorfieldindex and reads every attachment of that model class, or every file in that field. The existence queries in the same trait already cast the parent key withDbDongle::cast(..., 'TEXT'); this does the same for the plain and eager lookups.Median times on MySQL 8.0.45. The
filestable uses Winter'ssystem_filescolumns and indexes, filled with synthetic rows across 40 model classes, and storm's per-request query memo is disabled:files$user->avatar()->get()developwith('avatar'), 25 parents, developEXPLAIN, developEXPLAIN, this PRindex_merge, 6 rowsref, 1 rowindex_merge, 27 rowsref, 1 rowref, 2,510 rowsref, 1 rowindex_merge, 1,791 rowsref, 1 rowindex_merge, 3,534 rowsref, 1 rowref, 46,226 rowsref, 1 rowHow bad it gets depends on how files are spread over classes and fields. Real tables are usually far more skewed than this synthetic one. On our production site's
system_files(96k rows, a third of them attached to invoices), a single invoice PDF lookup takes 163 ms with an integer key, reading 32,963field = 'pdf'index entries. With a string key it takes 0.05 ms and reads 1 row (EXPLAIN ANALYZE).Change
addConstraints()binds the parent key as a string. Anullkey staysnull.addEagerConstraints()keeps Laravel's approach for integer keys: they are still inlined, with no placeholder per key, but as quoted string literals (in ('1', '2', '3')). Using bindings instead would hit the placeholder limits on large eager loads, such as 999 on older SQLite. Non-integer keys go throughwhereIn()as before.Results are identical:
attachment_idis always written as a string, and the eager-load dictionary matches'1'and1to the same key.Tests
testParentKeyIsBoundAsStringandtestEagerLoadInlinesParentKeysAsStringsboth fail ondevelop.testEagerLoadWithoutParentschecks that an empty key list still compiles to valid SQL.This is independent of #251, but goes with it. #251 removes the
ORthat forces a full scan inwithDeferred(), and with that gone, this integer key is what's left stopping MySQL from usingattachment_id_index(the 1M-row step in that PR's chart). The benchmark, runner and raw results are onAIC-BV/storm@bench/attach-string-key.🤖 Generated with Claude Code