-
-
#指定範囲のデータテーブルを作成する
- #auther: Xiaoqiang
- #date: 2008-03-31
- テーブルrandnumberを作成する
- 数値として-1を選択する
- union
- select -2
- union
- 選択-3
- ユニオン
- 選択-4
- ユニオン
- 選択-5
- ユニオン
- 選択0
- ユニオン
- 選択1
- ユニオン
- 選択2
- ユニオン
- 選択3
- ユニオン
- 選択4
- ユニオン
- 選択5 < ;p>#乱数を取得します
- #作成者: Xiaoqiang (占い師)
- #日付: 2008-03-31
- randnumber から数値を選択
- rand() 制限 1 で注文
-
コードをコピー
利点: 乱数はデータの特定の部分を指定でき、連続している必要はありません。
短所: 乱数の範囲が非常に広い場合、テーブルの作成がより困難になります。
2. MySQL の ROUND() と RAND() 関数を使用して実装します
-
- #SQL ステートメント 1 つで実行できます
- SELECT ROUND((0.5-RAND())*2*5)
- #注意
- #0.5-rand() は -0.5 から +0.5 までの乱数を取得できます
- #( 0.5-rand())*2 は -1 から +1 までの乱数を取得できます
- #(0.5-rand())*2*5 は -5 から +5 までの乱数を取得できます
- #ROUND((0.5- RAND( ))*2*5) は、-5 から +5 までのランダムな整数を取得できます
コードをコピー
しかし、その後、MYSQL の公式マニュアルを確認したところ、その中にある RAND() のヒントは、おそらく次のことを意味します。 ORDER 内 RAND() 関数は、データ列が複数回スキャンされるため、BY 句では使用できません。ただし、MYSQL 3.23 バージョンでも、ORDER BY RAND() を使用してランダム化を実現できます。
しかし、実際にテストしてみると、これは非常に非効率であることがわかりました。 150,000 項目を超えるデータベースでは、5 つのデータをクエリするのに 8 秒以上かかります。公式マニュアルを見ると、ORDER BY句に配置したrand()が複数回実行されると書かれており、当然ながら非常に非効率的です。
インターネットでは、基本的に max(id) * rand() をクエリしてデータをランダムに取得します。
-
- SELECT * FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2 WHERE t1.id >= t2.id ORDER BY t1.id ASC LIMIT 5;
コードをコピー
ただし、これにより 5 つの連続レコードが生成されます。解決策は、一度に 1 つのクエリを 5 回実行することだけです。それでも、150,000 のエントリを含むテーブルのクエリにかかる時間はわずか 0.01 秒未満であるため、それだけの価値があります。
次のステートメントでは、mysql フォーラムで誰かが使用している JOIN を使用しています。
-
- SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;
コードをコピー
meテストしてみると、所要時間は 0.5 秒で、速度は良好ですが、上記の記述とはまだ大きなギャップがあります。いつも何かが普通ではないように感じます。
そこで文を書き直しました。
-
- SELECT * FROM `table`
- WHERE id >= (SELECT Floor(RAND() * (SELECT MAX(id) FROM `table`)))
- ORDER BY id LIMIT 1;
コピーコード
これで、効率が再び向上し、クエリ時間はわずか 0.01 秒になりました
最後にステートメントを改良し、MIN(id) の判定を追加します。最初にテストしたとき、MIN(id) 判定を追加しなかったため、テーブルの最初の数行が常に半分の時間でクエリされていました。
完全なクエリ ステートメント:
-
- SELECT * FROM `table`
- WHERE id >= (SELECT Floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`) ) + (SELECT MIN(id) FROM `table`)))
- ORDER BY id LIMIT 1;
- SELECT *
- FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM ` table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
- WHERE t1.id >= t2.id
- ORDER BY t1。 id LIMIT 1;
コードをコピー
最後に、PHP でこれら 2 つのステートメントを 10 回クエリします。
前者には 0.147433 秒かかります
後者には 0.015130 秒かかります
JOIN 構文を使用する方が、WHERE で関数を直接使用するよりもはるかに効率的であるようです。
多くのテストを行った結果、結合構文を直接使用するよりも、より優れた提出物を持った友人が集まって他のユーザーとチャットできることがわかりました。
|