PERF: Add index for TopicTimer#topic_id (#17680)

When viewing a topic, we execute two queries to fetch the topic's
public topic timer and slow mode timer. The former query happens to be
able to use a unique index but the latter has to do a seq scan which is
slow. The query itself is not expensive but since viewing a topic is a
hot path, the little cuts add up overtime and the query itself
contributes significantly to the load of the database.
This commit is contained in:
Alan Guo Xiang Tan
2022-07-27 16:21:11 +08:00
committed by GitHub
parent 3682513475
commit dcf84fce7b
3 changed files with 10 additions and 2 deletions

View File

@ -1357,11 +1357,11 @@ class Topic < ActiveRecord::Base
end end
def public_topic_timer def public_topic_timer
@public_topic_timer ||= topic_timers.find_by(deleted_at: nil, public_type: true) @public_topic_timer ||= topic_timers.find_by(public_type: true)
end end
def slow_mode_topic_timer def slow_mode_topic_timer
@slow_mode_topic_timer ||= topic_timers.find_by(deleted_at: nil, status_type: TopicTimer.types[:clear_slow_mode]) @slow_mode_topic_timer ||= topic_timers.find_by(status_type: TopicTimer.types[:clear_slow_mode])
end end
def delete_topic_timer(status_type, by_user: Discourse.system_user) def delete_topic_timer(status_type, by_user: Discourse.system_user)

View File

@ -196,5 +196,6 @@ end
# Indexes # Indexes
# #
# idx_topic_id_public_type_deleted_at (topic_id) UNIQUE WHERE ((public_type = true) AND (deleted_at IS NULL)) # idx_topic_id_public_type_deleted_at (topic_id) UNIQUE WHERE ((public_type = true) AND (deleted_at IS NULL))
# index_topic_timers_on_topic_id (topic_id) WHERE (deleted_at IS NULL)
# index_topic_timers_on_user_id (user_id) # index_topic_timers_on_user_id (user_id)
# #

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddTopicTimersIndex < ActiveRecord::Migration[7.0]
def change
add_index :topic_timers, [:topic_id], where: "deleted_at IS NULL"
end
end