2012-01-07 6 views
2

を必要と私は2つのモデルがあります:ユーザーとスコアを>ユーザーが多くの得点Railsの3 - ユーザーのクエリを得点トップ - 新しいアプローチが

を持っているユーザーモデルがユーザーに関する一般的な情報が含まれ - 名前、場所などを モデルスコアには、日付、スコア、およびquality_scoreの値が含まれます。

私が必要とするのは、特定の日付範囲で最高のスコアを持つ20人のユニークユーザーのリストを取得する効率的な方法です。ユーザー1がトップ3のスコアを持つ場合、私は自分の名前に対して最高のスコアを、ユーザー2にとっては最高のスコアをもう一度自分の名前にします。 (私のテストデータは000sのユーザーと000000sのスコアを持っています)。

私は(他のSOのユーザーからの助けを借りて)これを使用してこの作業を行うために管理:

@top_users = User.limit(20). 
     select("`users`.*"). 
     joins(:scores). 
     where("datetime_utc >= ? AND datetime_utc <= ?", @utc_time_slot , @utc_time_slot_end). 
     group('user_id'). 
     order("max(quality_score) DESC, max(score) DESC") 

(マリオVisicとクリス・ベイリーのおかげで)が、クエリを実行するには容認できないほど長い時間がかかる - と私この作品を作るのにはるかに効率的な方法があると思うのを助けることができません...

どのポインタ/アイデアですか?ありがとう!

+0

品質スコアとスコアの違いは何ですか? –

+0

そのようなスピードスコアとスタイルスコア - annoyingly私は両方が必要です... – user1051849

+0

あなたのスコアの表のそれらのフィールドにインデックスがありますか? – smathy

答えて

0
最速のソリューションは usersテーブルにユーザーのベストスコアを非正規化することで

、および非正規化は、あなたのための現実的な選択肢ではない場合は、しかし、私はこれに応じて、scores.quality_scoreおよび/またはscores.datetime_utcにインデックスを作成することをお勧めインデックスクエリスコープをさらに減らすことができます。次に、私はこのように2でクエリを壊します:

top_user_scores = Score.limit(20). 
    where("datetime_utc >= ? AND datetime_utc <= ?", @utc_time_slot , @utc_time_slot_end). 
    group('user_id'). 
    order("max(quality_score) DESC, max(score) DESC") 
User.find(top_user_scores.map(&:user_id)) 
+0

こんにちは。私はそれをテストしますが、目に見えるだけで、これは私たちに最高20のスコア(<20人のユーザーかもしれない)を与えるユーザーはいませんか? – user1051849

+0

ああ、非正規化は、この悲しいことにメニューから外されています...あなたが求められる予定の時間範囲を知っていないので... – user1051849

+0

@andr - フォーマットに感謝します!私は次回よりうまくいくでしょう – Patrick

関連する問題