PERF: Use joins for `Post.for_mailing_list` instead of `NOT IN`.

PERF: Use joins for Post.for_mailing_list instead of NOT IN.

Joining on the topics table and then filtering the topics against a large set of ids is so much slower than doing a join on a sub query.

diff --git a/app/models/post.rb b/app/models/post.rb
index 8bca8c5..2a6ce57 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -86,15 +86,16 @@ class Post < ActiveRecord::Base
   scope :with_topic_subtype, ->(subtype) { joins(:topic).where('topics.subtype = ?', subtype) }
   scope :visible, -> { joins(:topic).where('topics.visible = true').where(hidden: false) }
   scope :secured, -> (guardian) { where('posts.post_type IN (?)', Topic.visible_post_types(guardian&.user)) }
+
   scope :for_mailing_list, ->(user, since) {
     q = created_since(since)
-      .joins(:topic)
-      .where(topic: Topic.for_digest(user, Time.at(0))) # we want all topics with new content, regardless when they were created
+      .joins("INNER JOIN (#{Topic.for_digest(user, Time.at(0)).select(:id).to_sql}) AS digest_topics ON digest_topics.id = posts.topic_id") # we want all topics with new content, regardless when they were created
+      .order('posts.created_at ASC')
 
     q = q.where.not(post_type: Post.types[:whisper]) unless user.staff?
-
-    q.order('posts.created_at ASC')
+    q
   }
+
   scope :raw_match, -> (pattern, type = 'string') {
     type = type&.downcase

GitHub sha: 6525613b