Improve query performance of attention requests count
What does this MR do and why?
In !74800 (merged), 2 indexes were added to merge_request_assignees
and merge_request_reviewers
tables to improve the performance of the finder query for attention requests.
In !80732 (merged), the finder query was used to show the count of attention requests.
While investigating a bug related to the count, found out that the count query isn't performant enough. Based on this query plan (https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9497/commands/33700), it takes around 447ms.
It's noticeable that the query plan isn't using the index added on the first MR when querying the merge_request_assignees
and merge_request_reviewers
tables.
To fix this, narrower indexes are added on both tables for user_id
and state
columns. This also deletes the state
indexes that were added before. The query timing dropped to 14ms from 447ms.
Query plan: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9497/commands/33717
Migrations
db:migrate
== 20220401044858 AddUserIdAndStateIndexToMergeRequestAssignees: migrating ====
-- transaction_open?()
-> 0.0000s
-- index_exists?(:merge_request_assignees, [:user_id, :state], {:where=>"state = 2", :name=>"index_on_merge_request_assignees_user_id_and_state", :algorithm=>:concurrently})
-> 0.0044s
-- execute("SET statement_timeout TO 0")
-> 0.0005s
-- add_index(:merge_request_assignees, [:user_id, :state], {:where=>"state = 2", :name=>"index_on_merge_request_assignees_user_id_and_state", :algorithm=>:concurrently})
-> 0.0033s
-- execute("RESET statement_timeout")
-> 0.0004s
== 20220401044858 AddUserIdAndStateIndexToMergeRequestAssignees: migrated (0.0173s)
== 20220401045116 AddUserIdAndStateIndexToMergeRequestReviewers: migrating ====
-- transaction_open?()
-> 0.0000s
-- index_exists?(:merge_request_reviewers, [:user_id, :state], {:where=>"state = 2", :name=>"index_on_merge_request_reviewers_user_id_and_state", :algorithm=>:concurrently})
-> 0.0023s
-- add_index(:merge_request_reviewers, [:user_id, :state], {:where=>"state = 2", :name=>"index_on_merge_request_reviewers_user_id_and_state", :algorithm=>:concurrently})
-> 0.0023s
== 20220401045116 AddUserIdAndStateIndexToMergeRequestReviewers: migrated (0.0069s)
== 20220401045621 RemoveStateIndexOnMergeRequestAssignees: migrating ==========
-- transaction_open?()
-> 0.0000s
-- indexes(:merge_request_assignees)
-> 0.0022s
-- remove_index(:merge_request_assignees, {:algorithm=>:concurrently, :name=>"index_on_merge_request_assignees_state"})
-> 0.0036s
== 20220401045621 RemoveStateIndexOnMergeRequestAssignees: migrated (0.0078s) =
== 20220401045642 RemoveStateIndexOnMergeRequestReviewers: migrating ==========
-- transaction_open?()
-> 0.0000s
-- indexes(:merge_request_reviewers)
-> 0.0020s
-- remove_index(:merge_request_reviewers, {:algorithm=>:concurrently, :name=>"index_on_merge_request_reviewers_state"})
-> 0.0022s
== 20220401045642 RemoveStateIndexOnMergeRequestReviewers: migrated (0.0060s) =
db:rollback
== 20220401045642 RemoveStateIndexOnMergeRequestReviewers: reverting ==========
-- transaction_open?()
-> 0.0000s
-- index_exists?(:merge_request_reviewers, :state, {:where=>"state = 2", :name=>"index_on_merge_request_reviewers_state", :algorithm=>:concurrently})
-> 0.0033s
-- execute("SET statement_timeout TO 0")
-> 0.0005s
-- add_index(:merge_request_reviewers, :state, {:where=>"state = 2", :name=>"index_on_merge_request_reviewers_state", :algorithm=>:concurrently})
-> 0.0047s
-- execute("RESET statement_timeout")
-> 0.0005s
== 20220401045642 RemoveStateIndexOnMergeRequestReviewers: reverted (0.0143s) =
== 20220401045621 RemoveStateIndexOnMergeRequestAssignees: reverting ==========
-- transaction_open?()
-> 0.0000s
-- index_exists?(:merge_request_assignees, :state, {:where=>"state = 2", :name=>"index_on_merge_request_assignees_state", :algorithm=>:concurrently})
-> 0.0033s
-- execute("SET statement_timeout TO 0")
-> 0.0004s
-- add_index(:merge_request_assignees, :state, {:where=>"state = 2", :name=>"index_on_merge_request_assignees_state", :algorithm=>:concurrently})
-> 0.0039s
-- execute("RESET statement_timeout")
-> 0.0004s
== 20220401045621 RemoveStateIndexOnMergeRequestAssignees: reverted (0.0128s) =
== 20220401045116 AddUserIdAndStateIndexToMergeRequestReviewers: reverting ====
-- transaction_open?()
-> 0.0000s
-- indexes(:merge_request_reviewers)
-> 0.0032s
-- execute("SET statement_timeout TO 0")
-> 0.0004s
-- remove_index(:merge_request_reviewers, {:algorithm=>:concurrently, :name=>"index_on_merge_request_reviewers_user_id_and_state"})
-> 0.0041s
-- execute("RESET statement_timeout")
-> 0.0004s
== 20220401045116 AddUserIdAndStateIndexToMergeRequestReviewers: reverted (0.0129s)
== 20220401044858 AddUserIdAndStateIndexToMergeRequestAssignees: reverting ====
-- transaction_open?()
-> 0.0000s
-- indexes(:merge_request_assignees)
-> 0.0034s
-- execute("SET statement_timeout TO 0")
-> 0.0004s
-- remove_index(:merge_request_assignees, {:algorithm=>:concurrently, :name=>"index_on_merge_request_assignees_user_id_and_state"})
-> 0.0027s
-- execute("RESET statement_timeout")
-> 0.0004s
== 20220401044858 AddUserIdAndStateIndexToMergeRequestAssignees: reverted (0.0113s)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.