4

全国的なエンジニアリング コンテストをサポートするアプリを再実装し、ローカル サーバーからクラウドに移行しています。

チームが現在どこに立っているかをチームに伝えるために、クエリの形式は次のとおりです。

select 1 + count(*) from team where where score < ?

チームのスコアは非常に動的に変化します。最大 200 万のチームが存在する可能性があり、これらのクエリを 1 秒あたり少なくとも 10 件処理する必要があります。

オリジナルは、チーム/スコア レコードの別のバークレー DB を使用することにより、必要なパフォーマンスを取得します (実際には 1999 のハードウェアで既に行われています)。Berkeley DB には、まさに適切な機能を提供する「レコード番号」機能があり、非常に高速です。

Heroku は明らかに Berkeley DB をサポートする方法がありません。彼らの標準 DB である PostgreSQL はselect count(*)、完全なテーブルまたはインデックス スキャンを実行しますが、これは遅すぎます。

続行する方法についてのアイデアはありますか?私は Heroku に慣れていませんが、何らかのクラウド ソリューションに移行する必要があります。

4

4 に答える 4

2

ランク テーブルを作成し、適切な頻度で更新します。カテゴリ (オープンまたは公式) とスコアを含めて、クエリ時にチーム テーブルに結合する必要がないようにします。

create table "rank" (
    team integer primary key, 
    category integer,
    score integer,
    rank_consolidated integer,
    rank_category integer
);

begin;
truncate table "rank"
;
insert into "rank" (team, category, score, rank_consolidated, rank_category)
select 
    team, category, score,
    rank() over(order by score desc) rank_consolidated,
    rank() over(partition by category order by score desc) rank_category
from team
;
commit
;
select * from "rank" where team = 11;

正確なランキング動作については、ウィンドウ関数を調べてください

于 2012-10-08T01:11:40.337 に答える
2

redisを使用して、チーム データをsorted set. 次に、ZRANK関数は必要な数を返します。Redis は一般的に非常に高速であり、ZRANK関数は O(log N) 期待されます。スキップリストで実装されています。

于 2012-10-08T14:00:52.710 に答える
0

スコアにインデックスを配置すると、テーブル全体のスキャンを回避できます。

于 2012-10-07T15:16:24.247 に答える