mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:23:25 +08:00
PERF: Optimize topic query for many categories (#20743)
Sites with many categories and many of them in muted by default (see `default_categories_muted`) reported bad performance when requesting the homepage as an anonymous user. This was the case because of the long query that iterated over topics and categories trying to remove those from the muted categories.
This commit is contained in:
parent
32aa821f12
commit
fb3c610f09
|
@ -288,20 +288,18 @@ module TopicGuardian
|
|||
topic&.access_topic_via_group.present? && authenticated?
|
||||
end
|
||||
|
||||
def filter_allowed_categories(records)
|
||||
def filter_allowed_categories(records, category_id_column: "topics.category_id")
|
||||
return records if is_admin? && !SiteSetting.suppress_secured_categories_from_admin
|
||||
|
||||
records =
|
||||
(
|
||||
if allowed_category_ids.size == 0
|
||||
records.where("topics.category_id IS NULL")
|
||||
else
|
||||
records.where(
|
||||
"topics.category_id IS NULL or topics.category_id IN (?)",
|
||||
allowed_category_ids,
|
||||
)
|
||||
end
|
||||
)
|
||||
if allowed_category_ids.size == 0
|
||||
records.where("#{category_id_column} IS NULL")
|
||||
else
|
||||
records.where(
|
||||
"#{category_id_column} IS NULL or #{category_id_column} IN (?)",
|
||||
allowed_category_ids,
|
||||
)
|
||||
end
|
||||
|
||||
records.references(:categories)
|
||||
end
|
||||
|
|
|
@ -776,7 +776,11 @@ class TopicQuery
|
|||
|
||||
result = apply_ordering(result, options)
|
||||
|
||||
all_listable_topics = @guardian.filter_allowed_categories(Topic.unscoped.listable_topics)
|
||||
all_listable_topics =
|
||||
@guardian.filter_allowed_categories(
|
||||
Topic.unscoped.listable_topics,
|
||||
category_id_column: "categories.id",
|
||||
)
|
||||
|
||||
if options[:include_pms] || options[:include_all_pms]
|
||||
all_pm_topics =
|
||||
|
@ -937,12 +941,12 @@ class TopicQuery
|
|||
].flatten.map(&:to_i)
|
||||
category_ids << category_id if category_id.present? && category_ids.exclude?(category_id)
|
||||
|
||||
list = list.where("topics.category_id IN (?)", category_ids) if category_ids.present?
|
||||
list = list.where("categories.id IN (?)", category_ids) if category_ids.present?
|
||||
else
|
||||
category_ids = SiteSetting.default_categories_muted.split("|").map(&:to_i)
|
||||
category_ids -= [category_id] if category_id.present? && category_ids.include?(category_id)
|
||||
|
||||
list = list.where("topics.category_id NOT IN (?)", category_ids) if category_ids.present?
|
||||
list = list.where("categories.id NOT IN (?)", category_ids) if category_ids.present?
|
||||
end
|
||||
|
||||
list
|
||||
|
|
Loading…
Reference in New Issue
Block a user