Commit 87e00ee7 authored by Sean McGivern's avatar Sean McGivern

Merge branch '25503_issues_finder_performance' into 'master'

Improve IssuableFinder performance

Closes #25503

See merge request !9030
parents 786adab1 d369acb5
...@@ -33,15 +33,17 @@ class IssuableFinder ...@@ -33,15 +33,17 @@ class IssuableFinder
items = by_scope(items) items = by_scope(items)
items = by_state(items) items = by_state(items)
items = by_group(items) items = by_group(items)
items = by_project(items)
items = by_search(items) items = by_search(items)
items = by_milestone(items)
items = by_assignee(items) items = by_assignee(items)
items = by_author(items) items = by_author(items)
items = by_label(items)
items = by_due_date(items) items = by_due_date(items)
items = by_non_archived(items) items = by_non_archived(items)
items = by_iids(items) items = by_iids(items)
items = by_milestone(items)
items = by_label(items)
# Filtering by project HAS TO be the last because we use the project IDs yielded by the issuable query thus far
items = by_project(items)
sort(items) sort(items)
end end
...@@ -107,8 +109,7 @@ class IssuableFinder ...@@ -107,8 +109,7 @@ class IssuableFinder
@project = project @project = project
end end
def projects def projects(items = nil)
return @projects if defined?(@projects)
return @projects = project if project? return @projects = project if project?
projects = projects =
...@@ -117,7 +118,7 @@ class IssuableFinder ...@@ -117,7 +118,7 @@ class IssuableFinder
elsif group elsif group
GroupProjectsFinder.new(group).execute(current_user) GroupProjectsFinder.new(group).execute(current_user)
else else
ProjectsFinder.new.execute(current_user) projects_finder.execute(current_user, item_project_ids(items))
end end
@projects = projects.with_feature_available_for_user(klass, current_user).reorder(nil) @projects = projects.with_feature_available_for_user(klass, current_user).reorder(nil)
...@@ -257,9 +258,9 @@ class IssuableFinder ...@@ -257,9 +258,9 @@ class IssuableFinder
def by_project(items) def by_project(items)
items = items =
if project? if project?
items.of_projects(projects).references_project items.of_projects(projects(items)).references_project
elsif projects elsif projects(items)
items.merge(projects.reorder(nil)).join_project items.merge(projects(items).reorder(nil)).join_project
else else
items.none items.none
end end
...@@ -314,13 +315,14 @@ class IssuableFinder ...@@ -314,13 +315,14 @@ class IssuableFinder
if filter_by_no_milestone? if filter_by_no_milestone?
items = items.left_joins_milestones.where(milestone_id: [-1, nil]) items = items.left_joins_milestones.where(milestone_id: [-1, nil])
elsif filter_by_upcoming_milestone? elsif filter_by_upcoming_milestone?
upcoming_ids = Milestone.upcoming_ids_by_projects(projects) upcoming_ids = Milestone.upcoming_ids_by_projects(projects(items))
items = items.left_joins_milestones.where(milestone_id: upcoming_ids) items = items.left_joins_milestones.where(milestone_id: upcoming_ids)
else else
items = items.with_milestone(params[:milestone_title]) items = items.with_milestone(params[:milestone_title])
items_projects = projects(items)
if projects if items_projects
items = items.where(milestones: { project_id: projects }) items = items.where(milestones: { project_id: items_projects })
end end
end end
end end
...@@ -334,9 +336,10 @@ class IssuableFinder ...@@ -334,9 +336,10 @@ class IssuableFinder
items = items.without_label items = items.without_label
else else
items = items.with_label(label_names, params[:sort]) items = items.with_label(label_names, params[:sort])
items_projects = projects(items)
if projects if items_projects
label_ids = LabelsFinder.new(current_user, project_ids: projects).execute(skip_authorization: true).select(:id) label_ids = LabelsFinder.new(current_user, project_ids: items_projects).execute(skip_authorization: true).select(:id)
items = items.where(labels: { id: label_ids }) items = items.where(labels: { id: label_ids })
end end
end end
...@@ -396,4 +399,8 @@ class IssuableFinder ...@@ -396,4 +399,8 @@ class IssuableFinder
def current_user_related? def current_user_related?
params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me' params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
end end
def projects_finder
@projects_finder ||= ProjectsFinder.new
end
end end
...@@ -41,4 +41,8 @@ class IssuesFinder < IssuableFinder ...@@ -41,4 +41,8 @@ class IssuesFinder < IssuableFinder
user_id: user.id, user_id: user.id,
project_ids: user.authorized_projects(Gitlab::Access::REPORTER).select(:id)) project_ids: user.authorized_projects(Gitlab::Access::REPORTER).select(:id))
end end
def item_project_ids(items)
items&.reorder(nil)&.select(:project_id)
end
end end
...@@ -20,4 +20,10 @@ class MergeRequestsFinder < IssuableFinder ...@@ -20,4 +20,10 @@ class MergeRequestsFinder < IssuableFinder
def klass def klass
MergeRequest MergeRequest
end end
private
def item_project_ids(items)
items&.reorder(nil)&.select(:target_project_id)
end
end end
---
title: Filter by projects in the end of search
merge_request: 9030
author:
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