Commit 4fd8162d authored by Michael Kozono's avatar Michael Kozono

Merge branch 'optimize-link-merge-request-worker' into 'master'

Optimize searching cherry-picked merge requests for linking deployments

See merge request gitlab-org/gitlab!58568
parents ed80138c ecd3104e
...@@ -288,9 +288,6 @@ class MergeRequest < ApplicationRecord ...@@ -288,9 +288,6 @@ class MergeRequest < ApplicationRecord
] ]
) )
end end
scope :by_cherry_pick_sha, -> (sha) do
joins(:notes).where(notes: { commit_id: sha })
end
scope :join_project, -> { joins(:target_project) } scope :join_project, -> { joins(:target_project) }
scope :join_metrics, -> (target_project_id = nil) do scope :join_metrics, -> (target_project_id = nil) do
# Do not join the relation twice # Do not join the relation twice
......
...@@ -215,6 +215,10 @@ class Note < ApplicationRecord ...@@ -215,6 +215,10 @@ class Note < ApplicationRecord
def simple_sorts def simple_sorts
super.except('name_asc', 'name_desc') super.except('name_asc', 'name_desc')
end end
def cherry_picked_merge_requests(shas)
where(noteable_type: 'MergeRequest', commit_id: shas).select(:noteable_id)
end
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
......
...@@ -66,8 +66,15 @@ module Deployments ...@@ -66,8 +66,15 @@ module Deployments
deployment.link_merge_requests(merge_requests) deployment.link_merge_requests(merge_requests)
picked_merge_requests = # The cherry picked commits are tracked via `notes.commit_id`
project.merge_requests.by_cherry_pick_sha(slice) # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22209
#
# NOTE: cross-joining `merge_requests` table and `notes` table could
# result in very poor performance because PG planner often uses an
# inappropriate index.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/321032.
mr_ids = project.notes.cherry_picked_merge_requests(slice)
picked_merge_requests = project.merge_requests.id_in(mr_ids)
deployment.link_merge_requests(picked_merge_requests) deployment.link_merge_requests(picked_merge_requests)
end end
......
---
title: Optimize searching cherry-picked merge requests for linking deployments
merge_request: 58568
author:
type: performance
...@@ -443,16 +443,6 @@ RSpec.describe MergeRequest, factory_default: :keep do ...@@ -443,16 +443,6 @@ RSpec.describe MergeRequest, factory_default: :keep do
end end
end end
describe '.by_cherry_pick_sha' do
it 'returns merge requests that match the given merge commit' do
note = create(:track_mr_picking_note, commit_id: '456abc')
create(:track_mr_picking_note, project: create(:project), commit_id: '456def')
expect(described_class.by_cherry_pick_sha('456abc')).to eq([note.noteable])
end
end
describe '.in_projects' do describe '.in_projects' do
it 'returns the merge requests for a set of projects' do it 'returns the merge requests for a set of projects' do
expect(described_class.in_projects(Project.all)).to eq([subject]) expect(described_class.in_projects(Project.all)).to eq([subject])
......
...@@ -863,6 +863,16 @@ RSpec.describe Note do ...@@ -863,6 +863,16 @@ RSpec.describe Note do
end end
end end
describe '.cherry_picked_merge_requests' do
it 'returns merge requests that match the given merge commit' do
note = create(:track_mr_picking_note, commit_id: '456abc')
create(:track_mr_picking_note, project: create(:project), commit_id: '456def')
expect(MergeRequest.id_in(described_class.cherry_picked_merge_requests('456abc'))).to eq([note.noteable])
end
end
describe '#for_project_snippet?' do describe '#for_project_snippet?' do
it 'returns true for a project snippet note' do it 'returns true for a project snippet note' do
expect(build(:note_on_project_snippet).for_project_snippet?).to be true expect(build(:note_on_project_snippet).for_project_snippet?).to be true
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment