2017-01-25 15 views
1

postgresが再帰的クエリを実行すると、一時的なテーブルが作成されます。 クエリが終了した後、プログラム全体が競合するまで、一時テーブルはディスク上に残ります。django/psycopg2からpostgresの再帰的クエリの一時テーブルをクリーンアップする方法

このプログラムは、独立したdb接続を持つすべてのワーカーのメインプロセスとマルチプロセッシングプールで構成されています(繰り返しデータソースを保持するため、メインプロセスの接続を閉じることはできません)。

膨大な量のデータがあるため、各クエリ後に一時テーブルを強制的にクリーンアップしたいと思います。

クエリは次のように実行される:

def process_datum(datum): 
    with db.connections['world'].cursor() as cursor: 
     cursor.execute("SELECT ... from query_function(%s)", (datum.id,)) 
     rows = cursor.fetchall() 
    for row in rows: 
     try: 
      ... 
      A_Model.objects.create(...) 
     except db.IntegrityError as e: 
      logger.warning("%s: %s", path, e) 

process_datumが作業者から呼び出され、query_functionが再帰クエリを実装するデータベース側テーブル関数です。

PS メインクエリは、次のとおりです。

select ... from features limit 1000 offset xxxx; 

クエリ機能は次のとおりです。クエリの作成

with recursive recursion(child_id, parent_id, node_id, path) as (
    select h.child_id, h.parent_id, h.parent_id as node_id, ARRAY[h.parent_id] 
    from hierarchy h 
    where h.direct=true and h.child_id=$1 
union all 
    select h.child_id, h.parent_id, r.node_id, r.path || ARRAY[h.parent_id] 
    from recursion r join hierarchy h on h.child_id = r.parent_id 
    where h.direct=true and h.parent_id != r.node_id 
) 
select * from recursion 

は、このようなものです:

insert into hierarchy (parent_id, child_id, direct, path) values (%d, %d, false, %s::bigint[]) 
+0

* postgresが再帰的クエリを実行すると、一時テーブルが作成されます。いいえ、そうではありません。あなたのフレームワークが一時テーブルを作成し、ワーカーを起動するように思えます。 PostgreSQLの 'WITH RECURSIVE'クエリは、一時テーブルを作成しません。 –

+0

一時データが/var/lib/postgres/.../base/pgsq_tmpに表示されます - それ以外に何ができますか? – qMax

+0

「再帰的」ではないのは、計算のためのメモリがあてはまらないということです。私は 'ORDER BY'を見ないので、おそらく' CTE'も一時ファイルを作成しますか? @CraigRinger? –

答えて

0

問題が原因偽に無限再帰にありましたデータ(循環リンク)。 私の場合、再帰的なクエリはそれを処理するために修正する必要があります。

+0

誰かがこれに直面している - postgresを'log_temp_files = 0'を実行すると、一時ファイルの作成に関する詳細が表示されます。 –

関連する問題