3

「スコア」列を持つリーダーボードがあります。また、スコア列にはインデックスがあり、500 万行であっても、トップ 10 または任意の数のスコアを切り出して、テーブルをスコアで非常に迅速に並べ替えることができます。

ただし、私が本当に望んでいるのは、リーダーボードにプレイヤーの「ランク」も表示することです。私はいくつかの方法を試しましたが、100000 行を超えるものを処理する場合、どれもスタックしていないようです (何百もの現在のユーザーが予想されることを考えると、これは長すぎるため、0.5 秒以上かかり始めます)。

私は現在、次のクエリを使用して 1 つのユーザー ランクを決定し、出力でこれより上のユーザーを単純にインクリメントしていますが、非常に遅いです。

SELECT  tro.score, tro.userId,  
(
    SELECT  count(*) 
    FROM    scoreboard tri
    WHERE   tri.score >= :score
) AS rank
FROM test_tracks tro
WHERE userId = :userID");

ユーザーがスコアボードに新しいスコアを挿入するたびにランクを「キャッシュ」するランキング テーブルを生成することを考えていますが、これを生成するだけでも長い時間 (数分、場合によっては数時間) かかります。

ランキングを確立するための良いガイドやコツを知っている人はいますか? できれば結果もページ化できるようにしたいのですが、当面はランクを確立するだけでも十分です!

前もって感謝します!

4

3 に答える 3

5

これを行う最善の方法は、より長いクエリを実行できるスケジュールによって定期的に (1 時間に 1 回、1 日に 1 回など) 更新されるテーブルを使用することです。この種の重いクエリで常にデータベースを破壊する必要はありません。また、長時間実行されるクエリが、そのページを閲覧するすべてのユーザーに対してではなく、たまに実行されることも意味します。

完璧な例は SO で、週/月/年の合計が 1 日 1 回更新されます。

于 2012-08-10T08:14:27.963 に答える
1

私が提案できる最高のものは次のとおりです。(私にとっては 500 万行で動作しますが、同時実行性はテストされていません。何らかの理由で InnoDB では非常に遅いですが、MyISAM テーブルでは 1 秒未満で動作するため、トランザクション サポートが失われます。)

ranks というテーブルを作成しました: ranks( score int PK, num int ) そして、これをシードしました: insert into ranks(score,num) select score,count(*) fromplayers group by score;

その後、このストアド プロシージャを作成しました。

DELIMITER $$
CREATE PROCEDURE testranks(
     OldScore INT 
    ,NewScore INT 
)
BEGIN
    INSERT INTO ranks (score,num) VALUES (NewScore,1) 
    ON DUPLICATE KEY 
    UPDATE num = num + 1;
    UPDATE ranks SET num = num - 1 WHERE score = OldScore;
    DELETE FROM ranks WHERE num = 0 AND score = OldScore;
    SELECT COUNT(*) FROM ranks WHERE score >= newscore;

END$$
DELIMITER ;

(古いスコアと新しいスコアを使用して) TestRanks を呼び出すと、新しいランクが返されます。

他の人がどのような解決策を思い付くかを知りたいと思っています。

于 2012-08-10T15:23:05.377 に答える
-1

私は最近、スコアに対するランキングを行いました。私は大まかなmysqlコードを投稿しています.これはあなたをさらに導くはずです.

SET @rank = 0, @prev_val = NULL;
SELECT id,rank, score FROM (
SELECT @rank := IF(@prev_val=score,@rank,@rank+1) AS rank,
@prev_val := score AS score, id
FROM rank ORDER BY score DESC
)AS result

テーブル名は「rank」、フィールドは id、score

お役に立てれば

于 2012-08-10T08:20:20.133 に答える