数値 random ランダムな行を選択する最良の方法PostgreSQL




5 Answers

両方の実行計画を調べて比較するには、以下を使用します。

EXPLAIN select * from table where random() < 0.01;
EXPLAIN select * from table order by random() limit 1000;

大きな表1を簡単にテストすると、 ORDER BY最初に完全な表をソートし、最初の1000項目を選択します。 大きなテーブルをソートすると、そのテーブルだけでなく、テンポラリファイルの読み書きも含まれます。 where random() < 0.1は、完全なテーブルを1回スキャンするだけです。

大規模なテーブルでは、完全な1つのテーブルスキャンでも時間がかかることがあるので、これは必要なものではありません。

3番目の提案は

select * from table where random() < 0.01 limit 1000;

これは、1000行が見つかると直ちにテーブルスキャンを停止し、より早く戻ります。 もちろん、これはランダム性を少し低下させますが、おそらくこれで十分です。

編集:この考慮事項の他に、あなたはこれについて既に質問された質問をチェックするかもしれません。 クエリ[postgresql] randomを使用するとかなりのヒット数を返します。

そしていくつかのアプローチを概説したdepezのリンクされた記事:

"完全なテーブルはメモリに収まらない"のように "大" 1

postgresql ダミー

私はPostgreSQLで行をランダムに選択したい、私はこれを試した:

select * from table where random() < 0.01;

しかし、他の人はこれをお勧めします:

select * from table order by random() limit 1000;

私は500万行の非常に大きなテーブルを持っています。

どのアプローチが良いですか? 違いは何ですか? ランダムな行を選択する最善の方法は何ですか?







ここに私のために働く決定があります。 私は理解して実行するのがとても簡単だと思います。

SELECT 
  field_1, 
  field_2, 
  field_2, 
  random() as ordering
FROM 
  big_table
WHERE 
  some_conditions
ORDER BY
  ordering 
LIMIT 1000;



1つの行だけが必要な場合は、 countから派生した計算offset使用できます。

select * from table_name limit 1
offset floor(random() * (select count(*) from table_name));



rという名前の列をserialという型で追加します。 インデックスr

200,000行があると仮定し、0 < n <= 200,000の乱数nを生成します。

r > n行を選択し、 ASCをソートして最小のものを選択します。

コード:

select * from YOUR_TABLE 
where r > (
    select (
        select reltuples::bigint AS estimate
        from   pg_class
        where  oid = 'public.YOUR_TABLE'::regclass) * random()
    )
order by r asc limit(1);

コードは自明です。 真ん中のサブクエリは、 https://.com/a/7945274/1271094 //.com/a/7945274/1271094からテーブルの行数をすばやく見積もるために使用されhttps://.com/a/7945274/1271094 。

アプリケーション・レベルでは、 n >行数または複数の行を選択する必要がある場合は、文を再度実行する必要があります。




Related