Improve filtering issues by label performance

This commit is contained in:
Felipe Artur 2017-12-26 17:16:43 -02:00
parent a5a0f3f725
commit 06d4f07a04
5 changed files with 123 additions and 14 deletions

View file

@ -5,8 +5,6 @@ module IssuesAction
# rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables
def issues def issues
@finder_type = IssuesFinder @finder_type = IssuesFinder
@label = finder.labels.first
@issues = issuables_collection @issues = issuables_collection
.non_archived .non_archived
.page(params[:page]) .page(params[:page])

View file

@ -5,7 +5,6 @@ module MergeRequestsAction
# rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables
def merge_requests def merge_requests
@finder_type = MergeRequestsFinder @finder_type = MergeRequestsFinder
@label = finder.labels.first
@merge_requests = issuables_collection.page(params[:page]) @merge_requests = issuables_collection.page(params[:page])

View file

@ -374,19 +374,14 @@ class IssuableFinder
end end
def by_label(items) def by_label(items)
if labels? return items unless labels?
if filter_by_no_label?
items = items.without_label
else
items = items.with_label(label_names, params[:sort])
items_projects = projects(items)
if items_projects items =
label_ids = LabelsFinder.new(current_user, project_ids: items_projects).execute(skip_authorization: true).select(:id) if filter_by_no_label?
items = items.where(labels: { id: label_ids }) items.without_label
end else
items.with_label(label_names, params[:sort])
end end
end
items items
end end

View file

@ -0,0 +1,5 @@
---
title: Fix timeout when filtering issues by label
merge_request:
author:
type: performance

View file

@ -0,0 +1,112 @@
# Creates a project with labeled issues for a user.
# Run this single seed file using: rake db:seed_fu FILTER=labeled USER_ID=74.
# If an USER_ID is not provided it will use the last created user.
require './spec/support/sidekiq'
class Gitlab::Seeder::LabeledIssues
include ::Gitlab::Utils
def initialize(user)
@user = user
end
def seed!
Sidekiq::Testing.inline! do
group = create_group
puts '.'
create_projects(group)
puts '.'
create_labels(group)
puts '.'
create_issues(group)
puts '.'
end
print '.'
end
private
def create_group
group_name = "group_of_#{@user.name}#{SecureRandom.hex(4)}"
group = Group.new(
name: group_name,
path: group_name,
description: FFaker::Lorem.sentence
)
group.save
group.add_owner(@user)
group
end
def create_projects(group)
5.times do
project_name = "project_#{SecureRandom.hex(6)}"
params = {
namespace_id: group.id,
name: project_name,
description: FFaker::Lorem.sentence,
visibility_level: Gitlab::VisibilityLevel.values.sample
}
Projects::CreateService.new(@user, params).execute
end
end
def create_labels(group)
group.projects.each do |project|
5.times do
label_title = FFaker::Vehicle.model
Labels::CreateService.new(title: label_title).execute(project: project)
end
end
10.times do
label_title = FFaker::Product.brand
Labels::CreateService.new(title: label_title).execute(group: group)
end
end
def create_issues(group)
# Get only group labels
group_labels =
LabelsFinder.new(@user, group_id: group.id).execute.where.not(group_id: nil)
group.projects.each do |project|
label_ids = project.labels.pluck(:id).sample(5)
label_ids.push(*group.labels.sample(4))
50.times do
issue_params = {
title: FFaker::Lorem.sentence(6),
description: FFaker::Lorem.sentence,
state: 'opened',
label_ids: label_ids
}
Issues::CreateService.new(project, @user, issue_params).execute if project.project_feature.present?
end
end
end
end
Gitlab::Seeder.quiet do
user_id = ENV['USER_ID']
user =
if user_id.present?
User.find(user_id)
else
User.last
end
Gitlab::Seeder::LabeledIssues.new(user).seed!
end