random() による並べ替えが、ランダムな行を取得する最悪の方法であることは既に知っています。random_number 列を追加し、ランダムな行を取得するときにその列を使用するソリューションを実装し、取得するたびに random_number を更新します。これはすべて、ランダムなプロキシ IP を返すサービスに参加するために使用されます。
select proxy_ip from proxy where random_number > 0.63 limit 1
0.63 は、アプリケーション内で生成される乱数の一例です。
問題は、「最悪の」ソリューションを使用する場合です。
select proxy_ip from proxy
order by random()
limit 1
サービスが呼び出されると、より高速に実行されるように見えます。sort by random()
テーブルには 9300 行が含まれているので、私の質問は、最悪のソリューションを作成するには、テーブルに何行含める必要があるかということです。
アプリケーションには、db で直接動作しないオーバーヘッドが少し発生します。代わりに、クエリを実行するデータ層を使用します。これにより、より優れたソリューションの実行速度が遅くなる理由が少し説明されます (さらに、1 つのクエリを実行しますrandom_number を更新する必要があるため、1 だけではありません)。
Explain Analyst の結果:
ランダムに並べ替え()
Limit (cost=837.03..837.03 rows=1 width=18) (actual time=34.954..34.956 rows=1 loops=1)
-> Sort (cost=837.03..860.46 rows=9373 width=18) (actual time=34.950..34.950 rows=1 loops=1)
Sort Key: (random())
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on proxy (cost=0.00..790.16 rows=9373 width=18) (actual time=0.013..17.951 rows=9363 loops=1)
Total runtime: 34.993 ms
ランダム列の使用:
Limit (cost=0.00..0.23 rows=1 width=18) (actual time=0.038..0.045 rows=1 loops=1)
-> Seq Scan on proxy (cost=0.00..790.16 rows=3481 width=18) (actual time=0.029..0.029 rows=1 loops=1)
Filter: (random_number > 0.63::double precision)
Total runtime: 0.078 ms
テーブルには 1 つのインデックスがあります。
CREATE UNIQUE INDEX proxy_pkey ON proxy USING btree (id)