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[])
* postgresが再帰的クエリを実行すると、一時テーブルが作成されます。いいえ、そうではありません。あなたのフレームワークが一時テーブルを作成し、ワーカーを起動するように思えます。 PostgreSQLの 'WITH RECURSIVE'クエリは、一時テーブルを作成しません。 –
一時データが/var/lib/postgres/.../base/pgsq_tmpに表示されます - それ以外に何ができますか? – qMax
「再帰的」ではないのは、計算のためのメモリがあてはまらないということです。私は 'ORDER BY'を見ないので、おそらく' CTE'も一時ファイルを作成しますか? @CraigRinger? –