SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【MySQL】ランダムにレコードを取り出す方法のひとつ

問題

MySQLで、ランダムに行を取り出したい。 order by rand() でいいの?

答え

よくあるのがこんな方法。

select * from t order by rand() limit 10;

レコード数が少ない場合は問題ない。

レコード数が何万行とある場合は大問題。order by句にrand()を使うと、全レコード数分のrand()を算出して、全レコードでソートをかける。ものすごく大変そうなのは容易に想像できる。

そこでwhere句にrand()を使う方法。

10万レコードから100件欲しいときは、100/100000 = 0.001なので、こうすると理論上100件取れる。

select * from t where rand() <= 0.001;

理屈はそうだけど、実際はちょっと余裕を持たせて、こうするとよい。

select * from t where rand() < 0.002 limit 100;

order by句で使うとソートが必要となるが、where句で使えば取ってくるだけ。

where句でrand()を使えば、limitの行数だけ取得したところでrand()の計算を終了できる。

補足

レコード数が少ない場合、運が悪いと1行も取れないことが考えられるので、状況に応じて使うとよい。

大量の会員データを使った抽選、ネットショップの商品が大量にあるときのランダム抽出など、大量のデータからランダムに取りたいときには有効。

パラメーターしだいでは、データベース内の格納順に影響されたりして、本当のランダムにはならないことが考えられるので、きちんとした抽選などをするには別途方法を考えたほうがよい。

関連するメモ

コメント