0

クエリの後に行をランダム化したいのですが、order by rand()120,000 行以上あるテーブルで使用するのは大変です。行数を出力するだけの小さなソリューションを見つけましたが、ランダムなインデックスから開始し、その後 #number of rows を返すように実行されます。これはかなり高速ですが、これはランダム インデックスの後にいくつかの行を返すだけです。コードは次のようになります。

SELECT *
FROM lieky AS r1 JOIN 
   (SELECT (RAND() *
                 (SELECT MAX(col_0)
                    FROM lieky)) AS id)
    AS r2
WHERE r1.col_0 >= r2.id
ORDER BY r1.col_0 ASC
LIMIT 100

ここで見つけました:http://jan.kneschke.de/projects/mysql/order-by-rand/

私を助けるものはありますか?

ランダム化されたデータをページネーションに取得しようとしているため、ユーザーがデータベースにクエリを実行すると、常にランダムな順序で行が取得されます。手伝ってくれてありがとう。

4

1 に答える 1

1

注意すべきこと

(SELECT (RAND() * (SELECT MAX(col_0) FROM lieky)) AS id)

MAX(col_0) を返すことができるため、1 行しか取得できません (WHERE r1.col_0 >= r2.id のため)。

私は良い解決策が次のようなものであるべきだと思います:

  • groupId int、seed int の 2 つの列を追加します。インデックスを追加indexName(groupId 、シード)
  • x 秒ごと (場合によっては 1 時間ごと、1 日ごとなど) に、これらの列を再計算するスクリプトを実行します (以下を参照)。
  • ユーザーが行リストを初めて開いたとき (またはアイテムを再表示したいとき) に、ランダムな groupId をユーザーのセッションに保存します。groupId は 0 から (lieky から max(groupId) を選択) の範囲で指定できます。
  • 次のようなクエリを使用して行を表示するには: (select * fromlieky where groupId=%saved groupId% order by Seed limit x,100) — 非常に高速なはずです

recalc スクリプトについては、かなり遅くなります (夜間に実行することをお勧めします)。
以下を使用して更新できるシード:

update lieky set Seed = rand()*1000000

次に、最初の N 行に GroupId=0 を設定し、次の N 行に GroupId=1 を設定します
。N は、ユーザーに表示できる最大行です (max_page)*(per_page_count)

于 2013-07-16T16:54:19.517 に答える