4

この質問は非常に多く寄せられていると感じているため、質問を差し控えましたが、まだ決定的な答えがありません。

オブジェクトテーブル: obj_id プライマリ キーとして UPC、EIN、ISBN で埋められた 4,000 万行以上。ギャップ

*Obj_Cat* テーブル: オブジェクトをカテゴリにリンクします。| の列 obj_id | cat_id |

質問: 5 つの連続していないランダムな obj_id を返す最良の方法は何ですか? 私が挙げた方法よりも良い方法はありますか?

解決策 1: SELECT objects.obj_id FROM objects left join obj_cat on objects.obj_id=obj_cat.obj_id WHERE obj_cat.cat_id=cat_id ORDER BY RAND() LIMIT 1; 5 回実行する

  • 大きなテーブルでは非常に遅くなります。

解決策 2: SELECT obj_id FROM objects WHERE obj_id >= (SELECT FLOOR( MAX(obj_id) * RAND()) FROMオブジェクト) LIMIT 1;を 5 回実行します (わかりやすくするために obj_cat 結合を含めませんでした)

  • 行にギャップがない場合、またはギャップが無視できる場合に最適なソリューションです。とても早い。

  • 必然的に番号付けにギャップが生じるため、カテゴリではうまく機能しません。

Solution3: Run を 5 回SELECT FLOOR(RAND() * COUNT(objects.*)) ASオフセットするFROM objects, obj_cat WHERE objects.obj_id=obj_cat.obj_id AND obj_cat.cat_id=cat_id; SELECT obj_id FROM objects LIMIT $offset, 1

  • 非常に柔軟です。ソリューション 1 よりもはるかに高速です。ギャップで機能します。ただし、40M 以上の行では、単一の 'LIMIT $offset, 1' に 1 分かかることがあります。

解決策 3 を使用しましたが、遅いです。私の現在の解決策は、fq でカテゴリを簡単に指定できるため、Solr の randomsortfield を使用することです。

Solr ソリューション: ?q=*&fl=obj_id&fq=cat:(cat_id)&sort=random_* desc&rows=5

  • 非常に高速で、カテゴリごとに約 45 秒かかりますが、5 つの非連続的な結果がすぐに返されます。

大規模なデータ セットを処理するときに、人々が発見したより良い方法はありますか? これは重複した質問のように思えますが、4,000 万以上のテーブルでの経験を貢献できると考えました。

4

1 に答える 1

0

これほど大きなデータセットでは、このようなオンザフライ計算を行うことはできません。時間とメモリのトレードオフを利用する必要があります。obj_catテーブルに、最大行数よりも広い幅の新しい符号なし整数インデックス列を作成し、各行に乱数を入力します。このようにして、乱数を生成し、最も近い一致を5回直接選択することができます。これは、ORDER BY RAND()を使用するよりも数桁速くなります。

于 2012-05-18T14:43:34.130 に答える