PERF: Use a subquery when excluding a tag from topic query. (#14577)

When a tag with alot of topics is used, we end up allocating a Ruby
array of all the topic ids. Instead, we can just use a subquery here and
handle all of the exclusion logic in PG.

Follow-up to ae13839f98
This commit is contained in:
Alan Guo Xiang Tan 2021-10-13 06:20:56 +08:00 committed by GitHub
parent 5ffb810c68
commit e3c724f79f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -693,8 +693,15 @@ class TopicQuery
result = result.where.not(id: TopicTag.distinct.pluck(:topic_id))
end
if @options[:exclude_tag] && tag = Tag.find_by(name: @options[:exclude_tag])
result = result.where.not(id: TopicTag.distinct.where(tag_id: tag.id).pluck(:topic_id))
if @options[:exclude_tag].present?
result = result.where(<<~SQL, name: @options[:exclude_tag])
topics.id NOT IN (
SELECT topic_tags.topic_id
FROM topic_tags
INNER JOIN tags ON tags.id = topic_tags.tag_id
WHERE tags.name = :name
)
SQL
end
end