あなたがほのめかしたように、本当にする唯一の方法 実行計画を比較することを知っています。実際、最良の方法はEXPLAIN ANALYZE
を使用することです。 、実際にクエリを実行し、結果を見積もりとともに出力に挿入するため、クエリプランナーと現実の感覚をつかむことができます。
ただし、一般的に、このような状況で私が行うことは、おそらく一時テーブルを作成することです。 クライアントサブセットの場合、次にJOIN
それをorders
に テーブル。オプションでWITH
を使用できます 代わりに、1つのクエリですべてを実行します。
つまり、次のようなものです:
CREATE TEMP TABLE tmp_clients AS
SELECT c.clientid
FROM clients c
WHERE c.city = 'New York'
ORDER BY c.clientid;
SELECT *
FROM orders AS o
JOIN tmp_clients AS c ON (o.clientid = c.clientid)
ORDER BY o.clientid;
このように、tmp_clients
ニューヨークのクライアント(最大5,000行)のみが含まれ、注文テーブルに結合されるのはそのテーブルです。
さらに最適化するために、一時テーブル(clientid)にインデックスを作成してから、ANALYZE
を作成することもできます。 JOIN
を実行する前に JOINが純粋にインデックスで行われるようにするため。いずれの場合もクエリプランをチェックして、相対的な違いを確認する必要があります(または、JOIN
の場合は、このことを念頭に置いてください。 思ったほど速くはありません)。
@poshestからのコメントへの回答:
一時テーブルのように聞こえます がスタックしているため、メモリフットプリントが増加し、長時間実行される接続の場合、機能がメモリリークのように見えます。
その場合、一時テーブルのように、それは本当のリークではありません。 接続にスコープされます。それらは自動的に消えますが、接続が終了するまでは消えません。ただし、使い終わったらすぐに消えるようにすることができます。単にDROP
テーブルは、使い終わったら他のテーブルと同じように、同じ種類の単調なメモリフットプリントを増やすことなく、同じ接続で何度も関数を呼び出すことができると思います。