From b9fe40b05fae29b7280374665647bd94b8052858 Mon Sep 17 00:00:00 2001 From: Terri Chu <tchu@gitlab.com> Date: Mon, 29 Mar 2021 04:55:47 +0000 Subject: [PATCH] Add preloading to fix N+1 queries in merge requests search [RUN ALL RSPEC] --- app/models/merge_request.rb | 2 +- .../fix-n-1-for-merge-requests-scope.yml | 5 +++++ ee/app/models/ee/merge_request.rb | 2 +- .../search/elastic/global_search_spec.rb | 19 ++++++++++++++----- 4 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 changelogs/unreleased/fix-n-1-for-merge-requests-scope.yml diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 834d28f1e3c7..ed4d19988ab1 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -358,7 +358,7 @@ def public_merge_status scope :preload_metrics, -> (relation) { preload(metrics: relation) } scope :preload_project_and_latest_diff, -> { preload(:source_project, :latest_merge_request_diff) } scope :preload_latest_diff_commit, -> { preload(latest_merge_request_diff: :merge_request_diff_commits) } - scope :with_web_entity_associations, -> { preload(:author, :target_project) } + scope :with_web_entity_associations, -> { preload(:author, target_project: [:project_feature, group: [:route, :parent], namespace: :route]) } scope :with_auto_merge_enabled, -> do with_state(:opened).where(auto_merge_enabled: true) diff --git a/changelogs/unreleased/fix-n-1-for-merge-requests-scope.yml b/changelogs/unreleased/fix-n-1-for-merge-requests-scope.yml new file mode 100644 index 000000000000..0b473f728935 --- /dev/null +++ b/changelogs/unreleased/fix-n-1-for-merge-requests-scope.yml @@ -0,0 +1,5 @@ +--- +title: Preload additional data to fix N+1 queries for merge request search +merge_request: 57284 +author: +type: performance diff --git a/ee/app/models/ee/merge_request.rb b/ee/app/models/ee/merge_request.rb index f95f4b2fd824..544933c1f7e6 100644 --- a/ee/app/models/ee/merge_request.rb +++ b/ee/app/models/ee/merge_request.rb @@ -82,7 +82,7 @@ def merge_requests_disable_committers_approval? class_methods do # This is an ActiveRecord scope in CE def with_api_entity_associations - super.preload(:blocking_merge_requests) + super.preload(:blocking_merge_requests, target_project: [group: :saml_provider]) end def sort_by_attribute(method, *args, **kwargs) diff --git a/ee/spec/features/search/elastic/global_search_spec.rb b/ee/spec/features/search/elastic/global_search_spec.rb index d5b108e12d23..e7837cf95256 100644 --- a/ee/spec/features/search/elastic/global_search_spec.rb +++ b/ee/spec/features/search/elastic/global_search_spec.rb @@ -5,6 +5,7 @@ RSpec.describe 'Global elastic search', :elastic, :sidekiq_inline do let(:user) { create(:user) } let(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) } + let(:projects) { create_list(:project, 5, :public, :repository, :wiki_repo) } before do stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true) @@ -22,7 +23,11 @@ control_count = ActiveRecord::QueryRecorder.new { visit path }.count expect(page).to have_css('.search-results') # Confirm there are search results to prevent false positives - create_list(object, 10, *creation_traits, creation_args) + projects.each do |project| + creation_args[:source_project] = project if creation_args.key?(:source_project) + creation_args[:project] = project if creation_args.key?(:project) + create(object, *creation_traits, creation_args) + end ensure_elasticsearch_index! @@ -40,7 +45,9 @@ let(:object) { :issue } let(:creation_args) { { project: project, title: 'initial' } } let(:path) { search_path(search: 'initial', scope: 'issues') } - let(:query_count_multiplier) { 0 } + # N+1 queries still exist and will be fixed per + # https://gitlab.com/gitlab-org/gitlab/-/issues/230712 + let(:query_count_multiplier) { 1 } it_behaves_like 'an efficient database result' end @@ -59,8 +66,8 @@ context 'searching merge requests' do let(:object) { :merge_request } - let(:creation_traits) { [:sequence_source_branch] } - let(:creation_args) { { source_project: project, title: 'initial' } } + let(:creation_traits) { [:unique_branches, :unique_author] } + let(:creation_args) { { title: 'initial', source_project: project } } let(:path) { search_path(search: '*', scope: 'merge_requests') } let(:query_count_multiplier) { 0 } @@ -71,7 +78,9 @@ let(:object) { :milestone } let(:creation_args) { { project: project } } let(:path) { search_path(search: '*', scope: 'milestones') } - let(:query_count_multiplier) { 0 } + # N+1 queries still exist and will be fixed per + # https://gitlab.com/gitlab-org/gitlab/-/issues/325887 + let(:query_count_multiplier) { 1 } it_behaves_like 'an efficient database result' end -- GitLab