Commit b9937fe6 authored by Stan Hu's avatar Stan Hu

Optimize issue search when sorting by due date and position

When searching for issues within a project or group, `IssuableFinder`
has an optimization that uses a CTE to filter the list of authorized
issues before searching within the list for text. This CTE optimization
fence is currently only used when the user specifies a simple sorting
parameter, such as `created_at`, and not popularity. These attributes
are generally stored directly with the model, so the CTE can easily do
an `ORDER BY` without joining another table (e.g. `award_emoji` for
popularity).

This commit adds the remaining simple sort attributes (due date,
relative position) the `Issue` class. This should help speed up the
search query and avoid a database statement timeout.

Improves https://gitlab.com/gitlab-org/gitlab/issues/34661
parent 6180d91a
...@@ -147,6 +147,20 @@ class Issue < ApplicationRecord ...@@ -147,6 +147,20 @@ class Issue < ApplicationRecord
'project_id' 'project_id'
end end
def self.simple_sorts
super.merge(
{
'closest_future_date' => -> { order_closest_future_date },
'closest_future_date_asc' => -> { order_closest_future_date },
'due_date' => -> { order_due_date_asc.with_order_id_desc },
'due_date_asc' => -> { order_due_date_asc.with_order_id_desc },
'due_date_desc' => -> { order_due_date_desc.with_order_id_desc },
'relative_position' => -> { order_relative_position_asc.with_order_id_desc },
'relative_position_asc' => -> { order_relative_position_asc.with_order_id_desc }
}
)
end
def self.sort_by_attribute(method, excluded_labels: []) def self.sort_by_attribute(method, excluded_labels: [])
case method.to_s case method.to_s
when 'closest_future_date', 'closest_future_date_asc' then order_closest_future_date when 'closest_future_date', 'closest_future_date_asc' then order_closest_future_date
......
---
title: Optimize issue search when sorting by due date and position
merge_request: 24217
author:
type: performance
...@@ -214,7 +214,9 @@ describe Issue do ...@@ -214,7 +214,9 @@ describe Issue do
it 'includes weight with other base keys' do it 'includes weight with other base keys' do
expect(Issue.simple_sorts.keys).to match_array( expect(Issue.simple_sorts.keys).to match_array(
%w(created_asc created_at_asc created_date created_desc created_at_desc %w(created_asc created_at_asc created_date created_desc created_at_desc
id_asc id_desc updated_desc updated_asc updated_at_asc updated_at_desc closest_future_date closest_future_date_asc due_date due_date_asc due_date_desc
id_asc id_desc relative_position relative_position_asc
updated_desc updated_asc updated_at_asc updated_at_desc
weight weight_asc weight_desc)) weight weight_asc weight_desc))
end end
end end
......
...@@ -84,6 +84,16 @@ describe Issue do ...@@ -84,6 +84,16 @@ describe Issue do
end end
end end
describe '.simple_sorts' do
it 'includes all keys' do
expect(described_class.simple_sorts.keys).to include(
*%w(created_asc created_at_asc created_date created_desc created_at_desc
closest_future_date closest_future_date_asc due_date due_date_asc due_date_desc
id_asc id_desc relative_position relative_position_asc
updated_desc updated_asc updated_at_asc updated_at_desc))
end
end
describe '#order_by_position_and_priority' do describe '#order_by_position_and_priority' do
let(:project) { create :project } let(:project) { create :project }
let(:p1) { create(:label, title: 'P1', project: project, priority: 1) } let(:p1) { create(:label, title: 'P1', project: project, priority: 1) }
......
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