Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2019-04-03 12:46:13 +0300
committerSean McGivern <sean@gitlab.com>2019-04-04 14:36:22 +0300
commit10ceb33ba271f603fa09d4a4b5fdca03fd7ea333 (patch)
treef96b0e786a4e2ef96287ac2099cb7fd89d8e3ebb /app/models/concerns/sortable.rb
parentf87b7fe3b386962c45e83486634352da544857fb (diff)
Extend CTE search optimisation to projects
When we use the `search` param on an `IssuableFinder`, we can run into issues. We have trigram indexes to support these searches. On GitLab.com, we often see Postgres's optimiser prioritise the (global) trigram indexes over the index on `project_id`. For group and project searches, we know that it will be quicker to filter by `project_id` first, as it returns fewer rows in most cases. For group issues search, we ran into this issue previously, and went through the following iterations: 1. Use a CTE on the project IDs as an optimisation fence. This prevents the planner from disregarding the index on `project_id`. Unfortunately it breaks some types of sorting, like priority and popularity, as they sort on a joined table. 2. Use a subquery for listing issues, and a CTE for counts. The subquery - in the case of group lists - didn't help as much as the CTE, but was faster than not including it. We can safely use a CTE for counts as they don't have sorting. Now, however, we're seeing the same issue in a project context. The subquery doesn't help at all there (it would only return one row, after all). In an attempt to keep total code complexity under control, this commit removes the subquery optimisation and applies the CTE optimisation only for sorts we know that are safe. This means that for more complicated sorts (like priority and popularity), the search will continue to be very slow. If this is a high-priority issue, we can consider introducing further optimisations, but this finder is already very complicated and additional complexity has a cost. The group CTE optimisation is controlled by the same feature flag as before, `attempt_group_search_optimizations`, which is enabled by default. The new project CTE optimisation is controlled by a new feature flag, `attempt_project_search_optimizations`, which is disabled by default.
Diffstat (limited to 'app/models/concerns/sortable.rb')
-rw-r--r--app/models/concerns/sortable.rb28
1 files changed, 15 insertions, 13 deletions
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 29e48f0c5f7..df1a9e3fe6e 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -21,19 +21,21 @@ module Sortable
class_methods do
def order_by(method)
- case method.to_s
- when 'created_asc' then order_created_asc
- when 'created_date' then order_created_desc
- when 'created_desc' then order_created_desc
- when 'id_asc' then order_id_asc
- when 'id_desc' then order_id_desc
- when 'name_asc' then order_name_asc
- when 'name_desc' then order_name_desc
- when 'updated_asc' then order_updated_asc
- when 'updated_desc' then order_updated_desc
- else
- all
- end
+ simple_sorts.fetch(method.to_s, -> { all }).call
+ end
+
+ def simple_sorts
+ {
+ 'created_asc' => -> { order_created_asc },
+ 'created_date' => -> { order_created_desc },
+ 'created_desc' => -> { order_created_desc },
+ 'id_asc' => -> { order_id_asc },
+ 'id_desc' => -> { order_id_desc },
+ 'name_asc' => -> { order_name_asc },
+ 'name_desc' => -> { order_name_desc },
+ 'updated_asc' => -> { order_updated_asc },
+ 'updated_desc' => -> { order_updated_desc }
+ }
end
private