Optimize Gitaly default_branch lookups in vulnerability statistics AdjustmentService
## Summary After !233509 batched the SQL N+1 in `Vulnerabilities::Statistics::AdjustmentService#default_branch_context_ids`, a Gitaly N+1 remains. Calling `project.default_branch_or_main` per project may trigger a Gitaly RPC if the repository's `root_ref` is not cached. ## Current code (after !233509) ```ruby def default_branch_context_ids branch_pairs = Project.id_in(project_ids).map { |project| [project.id, project.default_branch_or_main] } return [] if branch_pairs.empty? values_sql = Arel::Nodes::ValuesList.new(branch_pairs).to_sql Security::ProjectTrackedContext .where(context_type: :branch) .where("(project_id, context_name) IN (#{values_sql})") .limit(branch_pairs.length) .pluck(:id) end ``` The `.map { |project| project.default_branch_or_main }` may make 1 Gitaly call per project in the worst case (when `root_ref` is not cached). ## Possible approaches - Use a `find_each_with_relations` pattern that pre-loads root_refs - Pull default branches from an existing column or cache layer if available - Investigate batch RPC for Gitaly's `FindAllBranches` or similar ## Impact In practice, `root_ref` is cached aggressively (Rails cache), so this is mostly relevant for cold-cache scenarios. Worth optimizing if performance degrades in production telemetry, or if the project limit (`MAX_PROJECTS = 1000`) increases. ## References - Follow-up to https://gitlab.com/gitlab-org/gitlab/-/issues/597774 - Original review comment by @ghavenga in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/231378 - Related to https://gitlab.com/gitlab-org/gitlab/-/issues/555991
issue