From e3c724f79fb05c66e3240cb8fd85b24ce8725ca3 Mon Sep 17 00:00:00 2001 From: Alan Guo Xiang Tan Date: Wed, 13 Oct 2021 06:20:56 +0800 Subject: [PATCH] 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 ae13839f98b1b2530a4727a09feee89d7a6ebd88 --- lib/topic_query.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/topic_query.rb b/lib/topic_query.rb index 48aa18f0142..7bef13f38fc 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -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