Improve query performance for Dashboard::SnippetsController#index
This change addresses the snippet dashboard which is really slow at the moment. See https://gitlab.com/gitlab-org/gitlab-ce/issues/42877 for statistics.
It does this by:
- Change query in
Project.public_or_visible_to_user
toUNION
instead ofOR visibility_level IN (..)
and push down conditions - Add partial index on
project
to leverage index-only scan:(id) WHERE visibility_level IN (10, 20)
- Optimize
Project.public_or_visible_to_user
to omit the visibility check completely when given all levels available(0,10,20)
See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17088#note_59749778 for query comparison details.
Database Checklist
When adding migrations:
-
Updated db/schema.rb
-
Added a down
method so the migration can be reverted -
Added the output of the migration(s) to the MR body -
Added tests for the migration inspec/migrations
if necessary (e.g. when migrating data)
Migration:
== 20180213131630 AddPartialIndexToProjectsForIndexOnlyScans: migrating =======
-- index_exists?(:projects, :id, {:name=>"index_projects_on_id_partial_for_visibility"})
-> 0.0065s
-- transaction_open?()
-> 0.0000s
-- execute("SET statement_timeout TO 0")
-> 0.0002s
-- add_index(:projects, :id, {:name=>"index_projects_on_id_partial_for_visibility", :unique=>true, :where=>"visibility_level IN (10,20)", :algorithm=>:concurrently})
-> 0.0068s
== 20180213131630 AddPartialIndexToProjectsForIndexOnlyScans: migrated (0.0139s)
Rollback:
== 20180213131630 AddPartialIndexToProjectsForIndexOnlyScans: reverting =======
-- index_exists?(:projects, :id, {:name=>"index_projects_on_id_partial_for_visibility"})
-> 0.0072s
-- transaction_open?()
-> 0.0000s
-- select_one("SELECT current_setting('server_version_num') AS v")
-> 0.0003s
-- execute("SET statement_timeout TO 0")
-> 0.0002s
-- remove_index(:projects, {:algorithm=>:concurrently, :name=>"index_projects_on_id_partial_for_visibility"})
-> 0.0080s
== 20180213131630 AddPartialIndexToProjectsForIndexOnlyScans: reverted (0.0161s)
When adding or modifying queries to improve performance:
-
Included data that shows the performance improvement, preferably in the form of a benchmark -
Included the output of EXPLAIN (ANALYZE, BUFFERS)
of the relevant queries
General Checklist
-
Changelog entry added, if necessary -
Documentation created/updated -
API support added -
Tests added for this feature/bug - Review
-
Has been reviewed by Backend -
Has been reviewed by Database
-
-
Conform by the merge request performance guides -
Conform by the style guides -
Squashed related commits together
Edited by Yorick Peterse