PostgreSQLパフォーマンス向上に役立つ!ランダム行選択の高速化テクニック
PostgreSQLでランダムな行をすばやく選択する方法
PostgreSQLには、テーブルからランダムな行を効率的に選択するためのいくつかの方法があります。それぞれのアプローチには長所と短所があり、最適な方法は、選択する行数とテーブルのサイズによって異なります。
ORDER BY random() を使用する
最も基本的な方法は、ORDER BY random()
句を使用して結果をランダムに並べ替え、LIMIT 1
を使用して最初の行を選択することです。
SELECT *
FROM your_table
ORDER BY random()
LIMIT 1;
この方法はシンプルで理解しやすいですが、大きなテーブルの場合は非効率的になる可能性があります。ORDER BY
句は、結果をソートする必要があるため、テーブル全体をスキャンする必要があるからです。
サブクエリを使用する
より効率的な方法は、サブクエリを使用してランダムな行の ID を取得してから、その ID を使用してメインクエリで実際の行を選択することです。
SELECT *
FROM your_table
WHERE id = (
SELECT id
FROM your_table
ORDER BY random()
LIMIT 1
);
この方法は、ORDER BY random()
を使用するよりも効率的ですが、2 つのクエリを実行する必要があるため、少し複雑になります。
row_number() と dense_rank() を使用する
PostgreSQL 9.5 以降では、row_number()
と dense_rank()
関数を使用して、ランダムな行をより効率的に選択できます。
SELECT *
FROM your_table
WHERE dense_rank() OVER (ORDER BY random()) = 1;
この方法は、サブクエリを使用するよりもシンプルで効率的ですが、PostgreSQL 9.5 以降でのみ使用できます。
ARRAY と RANDOM() を使用する
PostgreSQLには、ARRAY
と RANDOM()
関数を使用して、ランダムな行の ID の配列を生成する方法もあります。
SELECT *
FROM your_table
WHERE id = ANY (
SELECT array_agg(id)
FROM your_table
ORDER BY random()
LIMIT 1
);
最適な方法を選択する
選択する行数とテーブルのサイズに応じて、最適な方法は異なります。
- 少数の行を選択する必要がある場合は、ORDER BY random() を使用する方が簡単です。
- 大きなテーブルからランダムな行を選択する必要がある場合は、サブクエリ、row_number() と dense_rank()』、またはARRAYとRANDOM()` を使用する方が効率的です。
その他の考慮事項
- インデックスがある場合は、パフォーマンスを向上させるために使用できます。
- 結果のセットが大きい場合は、
LIMIT
句を使用して必要な行数のみを選択できます。 - 重複を避ける必要がある場合は、
DISTINCT
句を使用できます。
例
以下の例では、customers
テーブルからランダムな顧客 1 件を選択する方法を示します。
SELECT *
FROM customers
ORDER BY random()
LIMIT 1;
このクエリは、customers
テーブル内のすべての顧客からランダムに 1 件の顧客を選択し、その顧客のすべての情報を含む行を返します。
PostgreSQLでランダムな行をすばやく選択するためのサンプルコード
このセクションでは、PostgreSQLでランダムな行をすばやく選択するためのいくつかのサンプルコードを紹介します。
ORDER BY random() を使用する
SELECT *
FROM customers
ORDER BY random()
LIMIT 1;
サブクエリを使用する
SELECT *
FROM customers
WHERE id = (
SELECT id
FROM customers
ORDER BY random()
LIMIT 1
);
このコードは、customers
テーブルからランダムな顧客 1 件を選択し、その顧客のすべての情報を含む行を返します。この方法は、ORDER BY random()
を使用するよりも効率的ですが、少し複雑になります。
row_number() と dense_rank() を使用する
SELECT *
FROM customers
WHERE dense_rank() OVER (ORDER BY random()) = 1;
ARRAY と RANDOM() を使用する
SELECT *
FROM customers
WHERE id = ANY (
SELECT array_agg(id)
FROM customers
ORDER BY random()
LIMIT 1
);
注: これらの例は、customers
テーブルという名前のテーブルを使用しています。使用するテーブル名に合わせてコードを変更する必要があります。
PostgreSQLでランダムな行をすばやく選択するその他の方法
前述の方法に加えて、PostgreSQLでランダムな行をすばやく選択する方法は他にもいくつかあります。
FETCH RANDOM を使用する
PostgreSQL 10以降では、FETCH RANDOM
句を使用してランダムな行を選択できます。
SELECT *
FROM your_table
FETCH RANDOM 1;
PL/vSQLを使用して、ランダムな行を選択する独自の関数を作成することもできます。これは、より複雑な要件がある場合に役立ちます。
CREATE FUNCTION random_row(table_name text)
RETURNS TABLE AS $$
DECLARE
row_id INTEGER;
BEGIN
SELECT random_int() * (SELECT count(*) FROM table_name)
INTO row_id;
RETURN QUERY
SELECT *
FROM table_name
WHERE id = row_id;
END;
$$ LANGUAGE plvsql;
このコードは、random_row
という名前の関数を作成します。この関数は、テーブル名を渡され、そのテーブルからランダムな行を返します。
外部ライブラリを使用する
SELECT *
FROM your_table
ORDER BY random_sample(1);
- 大きなテーブルからランダムな行を選択する必要がある場合は、plvsql または外部ライブラリを使用する方が効率的になる可能性があります。
postgresql random