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

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

diff --git a/lib/topic_query.rb b/lib/topic_query.rb
index 48aa18f..7bef13f 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
 

GitHub sha: e3c724f79fb05c66e3240cb8fd85b24ce8725ca3

This commit appears in #14577 which was approved by SamSaffron. It was merged by SamSaffron.