ORDER BY RAND() vs RAND() + GROUP BY: MySQLでランダム抽出の高速化
MySQLで60万行のテーブルからランダムに10行を高速に抽出する方法
この解説では、MySQLを使用して60万行のテーブルからランダムに10行を高速に抽出する方法について説明します。
方法
MySQLでランダムに10行を抽出するには、主に以下の2つの方法があります。
ORDER BY RAND()
とLIMIT 10
を使用するRAND()
関数とGROUP BY
を使用する
この方法は、ORDER BY RAND()
を使ってランダムな順序に並べ替え、LIMIT 10
を使って最初の10行を取得する方法です。
SELECT * FROM テーブル名 ORDER BY RAND() LIMIT 10;
この方法は、RAND()
関数を使ってランダムな値を生成し、GROUP BY
を使ってその値に基づいてグループ化し、各グループから1行ずつ取得する方法です。
SELECT * FROM (
SELECT *, RAND() AS rand_value FROM テーブル名
) AS t
GROUP BY rand_value
ORDER BY rand_value
LIMIT 10;
どちらの方法が高速か?
一般的には、ORDER BY RAND()
と LIMIT 10
を使用する方が高速です。しかし、テーブルのサイズやインデックスの状況によっては、RAND()
関数と GROUP BY
を使用する方が高速になる場合もあります。
パフォーマンスを向上させるためのヒント
- テーブルに
PRIMARY KEY
またはUNIQUE
インデックスがある場合は、それをORDER BY
句で使用するとパフォーマンスが向上します。 RAND()
関数はCPU負荷が高いため、できるだけ少ない行に対して使用することが重要です。- 可能であれば、抽出する行数を減らすことでパフォーマンスを向上させることができます。
-- テーブル作成
CREATE TABLE IF NOT EXISTS テーブル名 (
id INT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
age INT NOT NULL
);
-- データ挿入
INSERT INTO テーブル名 (name, age) VALUES ('山田太郎', 20), ('佐藤花子', 30), ...;
-- ランダムに10行抽出 (ORDER BY RAND() と LIMIT 10)
SELECT * FROM テーブル名 ORDER BY RAND() LIMIT 10;
-- ランダムに10行抽出 (RAND() 関数と GROUP BY)
SELECT * FROM (
SELECT *, RAND() AS rand_value FROM テーブル名
) AS t
GROUP BY rand_value
ORDER BY rand_value
LIMIT 10;
上記のサンプルコードは、MySQL 5.7.x を使用しています。他のバージョンの MySQL を使用している場合は、コードを修正する必要がある場合があります。
SELECT * FROM テーブル名 WHERE RAND() < 0.016667 LIMIT 10;
この方法は、RAND()
関数を使ってランダムな値を生成し、WHERE
句を使ってその値が一定の範囲内にある行を取得する方法です。上記の例では、10行抽出する確率が約1.67%になるように設定しています。
- 外部ツールを使用する
mysqldump
や csvtool
などの外部ツールを使用して、ランダムに10行を抽出することもできます。
どの方法を選択するべきかは、データ量、パフォーマンス要件、およびその他の要件によって異なります。一般的には、データ量が少なければ、ORDER BY RAND()
と LIMIT 10
を使用する方が簡単で高速です。データ量が多い場合は、RAND()
関数と GROUP BY
を使用する方がパフォーマンスが向上する場合があります。
mysql sql random