GET /groups/:id/releases runs queries per release because GroupReleasesFinder discards the preloaded relation
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
Releases::GroupReleasesFinder#execute calls releases.preloaded if preload and drops the relation that call returns (group_releases_finder.rb#L26), so Release.preloaded (release.rb#L51) never applies. The project-level finder assigns it (releases_finder.rb#L25).
GET /groups/:id/releases asks the finder to preload (releases.rb#L452-456), and then loads the author, links, evidences, milestones and project of each release with queries of its own. The GraphQL group releases resolver calls the same finder with its default preload: true.
The call that drops the result came in with !83295 (merged), a refactor of this finder.
Two specs should have caught it and could not:
- The request spec "include_subgroups avoids N+1 queries" (releases_spec.rb#L1978-1995) requests an empty
groupwhile it creates the new releases undergroup1, and it calls a memoizedsubject, so only its first request is ever sent. - The finder spec (group_releases_finder_spec.rb#L43) checks that
Release.preloadedis called, which a scope called on a relation always does, not that the result is used.
Steps to reproduce
- In a group, create a project with one release.
- Request
GET /groups/:id/releasesand count the SQL queries (for example withActiveRecord::QueryRecorderin a request spec). - Add three more releases to the same project, with different authors, and request the list again.
Example Project
Not needed: the count is not visible through the API. The request spec in the linked merge request reproduces it.
What is the current bug behavior?
On master at 797e8e3c, the corrected request spec from the merge request measures 46 queries for one release and 73 for four: about nine more queries for every release in the response.
What is the expected correct behavior?
The number of queries does not grow with the number of releases on the page, as for GET /projects/:id/releases.
Relevant logs and/or screenshots
Failure/Error:
Expected a maximum of 46 queries, got 73:Output of checks
Found by reading the code while working on gitlab-mcp-server, which calls this endpoint, and measured on master with the corrected specs from the merge request. Not checked on GitLab.com, where the query count is not visible.
Possible fixes
Assign the relation, as ReleasesFinder does:
- releases.preloaded if preload
+ releases = releases.preloaded if preloadI have a merge request ready with the fix and with both specs corrected.