3

次のスキーマを持つ非常に大きなテーブル (10M または 100M を超えるレコード) があります。

id int 主キー、ルール int

ルールごとにランダムなエントリを選択したい。このクエリを試しましたが、時間がかかります (treenode はテーブルの名前です):

SELECT tmp.id,tmp.rule FROM treenode
LEFT JOIN (SELECT * FROM treenode ORDER BY RAND()) tmp ON (treenode.rule = tmp.rule)
GROUP BY tmp.rule;

データをハッシュテーブルとしてメモリに保持すると、膨大なメモリが必要になります。もう 1 つのオプションは、データベースから各グループを取得し、ランダムなエントリを選択することです。グループの数が約 10 万であるため、これらの数のクエリをデータベースに送信するには長い時間がかかります。

更新: この表は 1 回だけ入力され、変更はありません。ID とルールには穴があります。

4

2 に答える 2

2

多分私は何かが欠けていますが、あなたのクエリと同等のクエリの下にありませんか?

SELECT * FROM  ( SELECT * FROM treenode ORDER BY RAND()) x GROUP BY x.rule;

結合する必要がないため、高速になります。

于 2012-05-30T01:55:40.157 に答える
0

すべてのエントリを確認すると、このクエリよりも時間がかからないことがわかりました。そこで、rule*max(id)+id として列を追加し、その上にインデックスを作成しました (ビューを使用する必要がありますか?)。

次のクエリを実行します。

SELECT id,rule,temp FROM treenode where temp>? ORDER BY temp LIMIT 0,100000;

クライアントで、返されたすべてのエントリを確認し、バッファを埋めます。ルールが変更されるたびに、バッファからランダムなアイテムを選択してクリアします (インデックス = 0 を置きます)。次に、? を使用してクエリを再度実行します。最後に返された一時値の値として。

于 2012-05-30T16:33:19.530 に答える