1
c = Conversation.joins(:messages).random
>> Conversation Load (8.1ms)  SELECT `conversations`.* FROM `conversations` INNER JOIN `messages` ON `messages`.`conversation_id` = `conversations`.`id` ORDER BY created_at DESC, RAND() LIMIT 1

カウント:

c.messages.count
>> (5.7ms)  SELECT COUNT(*) FROM `messages` WHERE `messages`.`conversation_id` = 74

長さ:

c.messages.length
>> Message Load (1.2ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`conversation_id` = 82

上記の追加のクエリを実行しない方法は? INNER JOIN を使用してランダムな会話のメッセージを既に結合していると思いますが、それらの結果をカウントするために新しいクエリが実行されますか?

2 番目の問題は、特定の user_id を持つ結合されたすべてのメッセージを取得しようとすることです。

u = User with id 27 # has messages in 'c' results above
c.messages.where('user_id = ?', u.id).all
>> Message Load (5.3ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`conversation_id` = 82 AND (user_id = 27)

select を使用して、追加のクエリなしでこれを行いました。

c.messages.select { |msg| msg.user_id == u.id }
>> returns messages without query logged

これらのクエリを削減または最適化する方法については、引き続き感謝しています。

4

1 に答える 1

1

n+1 の問題を回避するために、includes代わりに使用してみてください。 Railscast #181 Ryan Bates による http://railscasts.com/episodes/181-include-vs-joins?view=asciicastは、違いを簡単に説明しています。joins

于 2012-09-12T01:34:17.563 に答える