0

特定のカテゴリ内のランダムな行を非常に迅速に選択する必要がある、高性能でスケーラブルなデータベースのバックエンドを設計しています。この全体像を示すために、それぞれが「カテゴリ」フィールドを持つ行の巨大なテーブルが1つあり、最大500の異なるカテゴリが存在する1000万行が含まれている可能性があります。

これらを選択する際のパフォーマンスを向上させるために最初に考えたのは、疑似コードが次のようになるように、カテゴリごとにインデックスが付けられた個別のルックアップテーブルを作成することでした。

  • lookup_tableのカテゴリ「example」で0から行数までの乱数を生成します

  • lookup_table WHERE category ='example' LIMIT random_number、1から行を選択します

これは、インデックスを使用して一致する行の行数を生成し、ランダムな行を選択してそれを取り出します。カテゴリごとに約20,000行を実行した後、行を選択するのに0.02秒以上かかっていたことがわかりました。これは、多くの同様の操作を同時に実行する場合には理想的ではありませんでした。

私の2番目の考えと今実行できるのは、個別のデータベースまたはルックアップテーブルのグループです。これは、データベースがスケーリングすると、カテゴリごとのテーブルでシャーディングの準備が整っているためです。ランダムルックアップは、テーブルカウントからの乱数で主キーに対して実行できるため、ほぼ瞬時に実行されます。

同様の経験を持つここのウィザードがこれについて共有する考えを持っているかどうか、または私が見逃している機能があれば、私は大いに感謝します。テーブルを500の奇数のカテゴリに分割することを検討しましたが、このシナリオではあまり役に立たないようでした。

ありがとう!

編集デザインに大きな影響を与えたもう1つの考慮事項は、各アイテムに複数のカテゴリがあり、それらのいずれかによってランダムに選択できる必要があることです。

4

1 に答える 1

1

LIMITを使用するのではなく、rndfloat型のルックアップテーブルに新しい列を追加します。(category、rnd)にインデックスを作成し、で初期化しUPDATE table SET rnd = RAND()ます。次に、以下を使用します。

SET $rndValue = RAND();
SELECT id FROM lookup_table WHERE category = 'example' AND rnd < @rndValue ORDER BY `rnd` DESC LIMIT 1;

ランダムな行を効率的に見つけるため。@rndValueが0になると行が見つからないため(またはそのカテゴリにオブジェクトがない場合)、これをループに入れることをお勧めします。

于 2012-05-10T10:52:43.263 に答える