我有两个关系如下:
class CfThread < ActiveRecord::Base
self.primary_key = 'thread_id'
self.table_name = 'cforum.threads'
belongs_to :forum, class_name: 'CfForum', :foreign_key => :forum_id
has_many :messages, class_name: 'CfMessage', :foreign_key => :thread_id
attr_accessible :thread_id, :tid, :slug, :forum_id, :archived, :created_at, :updated_at
end
class CfMessage < ActiveRecord::Base
has_one :owner, class_name: 'CfUser', :foreign_key => :user_id
has_many :flags, class_name: 'CfFlag'
belongs_to :thread, class_name: 'CfThread', :foreign_key => :thread_id
attr_accessible :message_id, :mid, :thread_id, :subject, :content,
:author, :email, :homepage, :deleted, :user_id, :parent_id,
:updated_at, :created_at
end
我想查询最后 10 个线程及其消息而不产生 n+1 查询情况:
@threads = CfThread.includes(:messages).order('cforum.threads.created_at DESC').limit(10)
这会使用 DISTINCT 产生一个非常慢的查询:
SELECT DISTINCT "cforum"."threads".thread_id, cforum.threads.created_at AS alias_0 FROM "cforum"."threads" LEFT OUTER JOIN "cforum"."messages" ON "cforum"."messages"."thread_id" = "cforum"."threads"."thread_id" ORDER BY cforum.threads.created_at DESC LIMIT 10
查询规划器想要对线程和消息进行全表扫描。
使用纯 SQL 很容易优化这种情况,但也有使用 AR 的方法吗?我可以避免 DISTINCT 而不产生 n+1 查询吗?
问候,CK
编辑:索引如下:
主题:
"threads_pkey" PRIMARY KEY, btree (thread_id)
"index_cforum.threads_on_slug" UNIQUE, btree (slug)
"index_cforum.threads_on_archived" btree (archived)
"index_cforum.threads_on_tid" btree (tid)
"threads_created_at_idx" btree (created_at, updated_at)
留言:
"messages_pkey" PRIMARY KEY, btree (message_id)
"index_cforum.messages_on_mid" btree (mid)
"index_cforum.messages_on_thread_id" btree (thread_id)