sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQL:大きなテーブルの小さなサブセットを結合するための最良の方法

    あなたがほのめかしたように、本当にする唯一の方法 実行計画を比較することを知っています。実際、最良の方法は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 テーブルは、使い終わったら他のテーブルと同じように、同じ種類の単調なメモリフットプリントを増やすことなく、同じ接続で何度も関数を呼び出すことができると思います。



    1. MySQL8ステートメントを選択して「Last_query_cost」を取得します

    2. スタックオーバーフローのように、顧客がWebサイトでopenidを使用できるようにするにはどうすればよいですか?

    3. SQL:各人に最も一般的な値を返す

    4. PHP mysqli Insertが機能しないが、エラーが発生しない