Skip to content

Commit

Permalink
PERF: improve performance of publish_notifications_state
Browse files Browse the repository at this point in the history
User.publish_notifications_state is called every time a notification is
created, this can become a very critical code path.

On some heavy notification related sites this can be a major CPU user on PG

This index makes it much cheaper to publish notification state, cause a
simple index lookup does the trick.
  • Loading branch information
SamSaffron committed May 14, 2019
1 parent dafc941 commit 6241845
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/models/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def send_email
#
# idx_notifications_speedup_unread_count (user_id,notification_type) WHERE (NOT read)
# index_notifications_on_post_action_id (post_action_id)
# index_notifications_on_read_or_n_type (user_id,id DESC,read,topic_id) UNIQUE WHERE (read OR (notification_type <> 6))
# index_notifications_on_user_id_and_created_at (user_id,created_at)
# index_notifications_on_user_id_and_id (user_id,id) UNIQUE WHERE ((notification_type = 6) AND (NOT read))
# index_notifications_on_user_id_and_topic_id_and_post_number (user_id,topic_id,post_number)
Expand Down
1 change: 1 addition & 0 deletions app/models/user_custom_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ class UserCustomField < ActiveRecord::Base
#
# Indexes
#
# idx_user_custom_fields_last_reminded_at (name,user_id) UNIQUE WHERE ((name)::text = 'last_reminded_at'::text)
# index_user_custom_fields_on_user_id_and_name (user_id,name)
#
23 changes: 23 additions & 0 deletions db/migrate/20190514055014_add_read_notification_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true
class AddReadNotificationIndex < ActiveRecord::Migration[5.2]
disable_ddl_transaction!

def up
# doing this by hand cause I am ordering id DESC
execute <<~SQL
CREATE UNIQUE INDEX CONCURRENTLY index_notifications_on_read_or_n_type
ON notifications(user_id, id DESC, read, topic_id)
WHERE read or notification_type <> 6
SQL

# we need to do this to ensure this index hits
# on some sites this was missing prior
execute <<~SQL
VACUUM ANALYZE notifications
SQL
end

def down
raise ActiveRecord::IrreversibleMigration
end
end

0 comments on commit 6241845

Please sign in to comment.