こんにちは、フリーランスエンジニアのせいや(@knkSeiya)です。
先日、MySQLでランダムにレコードを取得したい機会がありました。
そういえばどういうクエリを書けばランダムにレコードが取れるんだっけ?ってなったのでその備忘録です。
タップできる目次
MySQLでランダムにレコードを取得する
MySQLでランダムにレコードを取得するのはいくつかの方法があるようですが、今回は一番簡単な方法を紹介します。
方法:ORDER BY RAND()を使う
クエリにORDER BYを指定し、RAND()を使います。
例として、以下のテーブルを用意しました。
mysql> DESC fruits;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM fruits;
+----+--------------+
| id | name |
+----+--------------+
| 1 | りんご |
| 2 | バナナ |
| 3 | メロン |
| 4 | いちご |
| 5 | オレンジ |
+----+--------------+
5 rows in set (0.00 sec)
このテーブルからランダムにレコードを取得してみます。
mysql> SELECT * FROM fruits ORDER BY RAND() LIMIT 1;
+----+-----------+
| id | name |
+----+-----------+
| 4 | いちご |
+----+-----------+
1 row in set (0.00 sec)
取れました⊂(´ω`)⊃
だけど注意点があって、RAND()でORDER BYすると「Using temporary; Using filesort」が使われるようです。
mysql> EXPLAIN SELECT * FROM fruits ORDER BY RAND() LIMIT 1;
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| 1 | SIMPLE | fruits | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | Using temporary; Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
1 row in set, 1 warning (0.00 sec)
レコード数が少なければORDER BY RAND()は一番簡単にランダム取得できる方法ですが、大量のレコードに実行するのは危険です。たぶんめっちゃ遅くなります( ; ^ω^ )
- レコードのランダム取得は「ORDER BY RAND()」が簡単
- Using temporary; Using filesortになる(データ量によっては遅くなる)
おまけ:FuelPHPのORMでの指定
FuelPHPのORMでのランダム取得の書き方。
find('first', ['order_by' => [DB::expr('RAND()')]])
FuelPHPのクエリビルダでMySQLの関数を使いたい場合はDB::expr()で囲ってやる必要があります。
せいや
用法・容量を守って正しくお使いください!(ぶん投げ