From aa85d7bccc72983fc5f39df53fc83748b397150a Mon Sep 17 00:00:00 2001
From: David Kim <dkim@gitlab.com>
Date: Thu, 8 Apr 2021 22:13:52 +0930
Subject: [PATCH] Add a new index to improve query performance

---
 ...otification_settings_query_performance.yml |  5 ++++
 ...nd_level_index_on_notification_settings.rb | 24 +++++++++++++++++++
 db/schema_migrations/20210402005225           |  1 +
 db/structure.sql                              |  4 +---
 4 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 changelogs/unreleased/improve_notification_settings_query_performance.yml
 create mode 100644 db/post_migrate/20210402005225_add_source_and_level_index_on_notification_settings.rb
 create mode 100644 db/schema_migrations/20210402005225

diff --git a/changelogs/unreleased/improve_notification_settings_query_performance.yml b/changelogs/unreleased/improve_notification_settings_query_performance.yml
new file mode 100644
index 0000000000000..9845df3d8ce99
--- /dev/null
+++ b/changelogs/unreleased/improve_notification_settings_query_performance.yml
@@ -0,0 +1,5 @@
+---
+title: Adjust indices to improve query performance for notification_settings
+merge_request: 58895
+author:
+type: performance
diff --git a/db/post_migrate/20210402005225_add_source_and_level_index_on_notification_settings.rb b/db/post_migrate/20210402005225_add_source_and_level_index_on_notification_settings.rb
new file mode 100644
index 0000000000000..a29babca93e97
--- /dev/null
+++ b/db/post_migrate/20210402005225_add_source_and_level_index_on_notification_settings.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddSourceAndLevelIndexOnNotificationSettings < ActiveRecord::Migration[6.0]
+  include Gitlab::Database::MigrationHelpers
+
+  DOWNTIME = false
+  INDEX_WITH_SOURCE_LEVEL_USER_NAME = 'index_notification_settings_on_source_and_level_and_user'
+  INDEX_WITH_SOURCE_NAME = 'index_notification_settings_on_source_id_and_source_type'
+  INDEX_WITH_USER_NAME = 'index_notification_settings_on_user_id'
+
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_index :notification_settings, [:source_id, :source_type, :level, :user_id], name: INDEX_WITH_SOURCE_LEVEL_USER_NAME
+    remove_concurrent_index_by_name :notification_settings, INDEX_WITH_SOURCE_NAME # Above index expands this index
+    remove_concurrent_index_by_name :notification_settings, INDEX_WITH_USER_NAME # It is redundant as we already have unique index on (user_id, source_id, source_type)
+  end
+
+  def down
+    add_concurrent_index :notification_settings, [:source_id, :source_type], name: INDEX_WITH_SOURCE_NAME
+    add_concurrent_index :notification_settings, [:user_id], name: INDEX_WITH_USER_NAME
+    remove_concurrent_index_by_name :notification_settings, INDEX_WITH_SOURCE_LEVEL_USER_NAME
+  end
+end
diff --git a/db/schema_migrations/20210402005225 b/db/schema_migrations/20210402005225
new file mode 100644
index 0000000000000..767b1307ca7b5
--- /dev/null
+++ b/db/schema_migrations/20210402005225
@@ -0,0 +1 @@
+6c44623655732e9c2916f7a71d51f53e819a216b8936d20d28d6acf37cc94fdf
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 16b69a4370ea5..439e8f8f66b5b 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -23220,9 +23220,7 @@ CREATE INDEX index_notes_on_project_id_and_noteable_type ON notes USING btree (p
 
 CREATE INDEX index_notes_on_review_id ON notes USING btree (review_id);
 
-CREATE INDEX index_notification_settings_on_source_id_and_source_type ON notification_settings USING btree (source_id, source_type);
-
-CREATE INDEX index_notification_settings_on_user_id ON notification_settings USING btree (user_id);
+CREATE INDEX index_notification_settings_on_source_and_level_and_user ON notification_settings USING btree (source_id, source_type, level, user_id);
 
 CREATE UNIQUE INDEX index_notifications_on_user_id_and_source_id_and_source_type ON notification_settings USING btree (user_id, source_id, source_type);
 
-- 
GitLab