Fix duplicate query problem in `boards/issues`
What does this MR do?
When loading https://gitlab.com/gitlab-org/gitlab/-/boards, I spotted a duplicate query that could sometimes take 50ms or longer, so wasn't exactly cheap:
SELECT issues.*, (SELECT MIN("label_priorities"."priority") FROM "labels" LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id" INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id" WHERE (label_priorities.project_id = issues.project_id) AND (label_links.target_id = issues.id) AND "label_links"."target_type" = 'Issue') AS highest_priority FROM "issues" WHERE "issues"."project_id" = 278964 AND ("issues"."state_id" IN (1)) AND (EXISTS (SELECT true FROM "issue_assignees" WHERE "issue_assignees"."user_id" IN (4447636) AND issue_id = issues.id)) GROUP BY "issues"."id" ORDER BY relative_position ASC NULLS LAST, highest_priority ASC NULLS LAST, id DESC LIMIT 21 OFFSET 0
The query fires twice, first when loading & filtering issues
, then again during the rendering phase, so that the overall execution path looks something like this:
-
::Boards::IssuesController.index
- create
issues
scope, then fix ordering by callingIssue.move_nulls_to_end
- since this function iterates the collection, this forces the first query execution
- change
issues
scope topreload
other associations; this invalidates the scope and the previously loaded issues - call
render_issues
- this will fire the query again, since
loaded?
will befalse
for the collection
- this will fire the query again, since
- create
I was able to reproduce this locally and fixed this by moving up the preload
call, eager-loading issues, and only then calling Issue.move_nulls_to_end
and render_issues
. This makes it easier to reason about this code as well since it's clear at which time the query executes.
Screenshots
Does this MR meet the acceptance criteria?
Conformity
Edited by 🤖 GitLab Bot 🤖