MySQL の order by rand()

MySQL のレコード取り出しの際に、ソートをランダムにできないものかと調べていたら、あった。

SELECT * FROM table ORDER BY RAND()

こんな感じで。ソートを RAND にすれば良いという…

そうそう、僕もこれは最近知ったんですが。Haropy でエントリーをランダムに取り出すのにも order by rand() を使ってます。Class::DBI::mysqlretrieve_random というメソッドがあって、ランダムに一見取り出すことができるという。これも中では order by rand() limit 1 をやってます。

ただ、この rand() はデータ量が大きいテーブルには使いづらいという罠。

mysql> explain select id from entry order by rand() limit 1 ?G
*************************** 1. row ***************************
        table: entry 
        type: indexpossible_keys: NULL  
        key: PRIMARY
        key_len: 32  
        ref: NULL
        rows: 3794
        Extra: Using index; Using temporary; Using filesort
1 row in set (0.00 sec)

インデックスをかけてるテーブルでも、結局ランダムなので全件捜査してから値を返す。プライマリーキーに対して rand() する場合でも O(1) ではないのですよね。なんか回避する方法があったりするのかな。

追記

limit 1 のあとの「?G」に見えるのはなんか Mac のターミナルからコピるとこうなっちゃう罠。ほんとはバックスラッシュ。どうやって直すのこれ。