非常に大きなテーブルでグループ化されたランキングが必要です。この問題の解決策がいくつか見つかりました。たとえば、この投稿や Web 上の他の場所です。ただし、これらのソリューションの最悪の場合の複雑さを把握することはできません。特定の問題は、各行に多数のポイントと関連付けられた名前が含まれるテーブルで構成されています。1~4等のランク間隔をリクエストできるようにしたい。以下にいくつかのデータ例を示します。
name | points
Ab 14
Ac 14
B 16
C 16
Da 15
De 13
これらの値を使用して、次の「ランキング」が作成されます。
Query id | Rank | Name
1 1 B
2 1 C
3 3 Da
4 4 Ab
5 4 Ac
6 6 De
また、クエリ ID で次の間隔を作成できるはずです: 2-5 ランクを与える: 1、3、4、および 4。
データベースには約 300 万件のレコードが保持されているため、できれば log(n) よりも複雑なソリューションは避けたいと考えています。データベースでは常に更新と挿入が行われるため、これらのアクションも log(n) の複雑さで実行する必要があります。それが可能かどうかはわかりませんが、しばらくの間、頭を抱えてみました。二分探索が可能であるという結論に達しましたが、これを行うクエリを作成できませんでした。MySQL サーバーを使用しています。
フィルタリングの疑似コードがどのように機能するかについて詳しく説明します。まず、(points, name) のインデックスが必要です。入力としてfromrankとtilrankを与えます。データベース内のレコードの総数は n です。擬似コードは次のようになります。
中央値を見つけ、この値よりも少ない行を数えます (この数は、同じ量のポイントを持つものを考慮せずに、ランクの大まかな推定値を示します)。返された数値が fromrank 区切り文字よりも大きい場合、前半を細分化し、中央値を見つけます。fromrank を開始するポイントの量が特定されるまで、これを続けます。次に、名前 index を使用してそのポイント数内で同じことを行い、正しい行に到達するまで中央値を見つけます。ティルランクについてもまったく同じことを行います。
結果は log(n) 数のサブディビジョンになるはずです。したがって、中央値とカウントを log(n) 時間で作成できる場合、最悪の場合の複雑さ log(n) で問題を解決できるはずです。私が間違っている場合は修正してください。