【发布时间】:2017-01-25 07:51:59
【问题描述】:
当 postgres 运行递归查询时,它会为其创建临时表。 查询完成后,临时表保留在磁盘上,直到整个程序运行完毕。
该程序由主进程和多进程工作池组成,所有这些都具有单独的数据库连接(我无法关闭主进程的连接,因为它包含迭代数据源)。
我想强制 postgres 在每次查询后清理那些临时表,因为数据量很大。
查询以下列方式执行:
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是从worker调用的,query_function是实现递归查询的数据库端表函数。
附言 主要查询是:
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 -- 还能是什么?
-
这不是关于
recursive而是关于不适合用于计算的内存。我没有看到ORDER BY,所以CTE也可能创建临时文件? @CraigRinger? -
问题似乎是由于虚假数据导致的无限递归。 ORDER BY 是怎么回事?
-
@qMax 这是临时表空间,它也用于
TEMPORARY表、排序假脱机文件等。我可以看到您现在已经编辑显示 is 实际上是一个WITH RECURSIVE查询,在这种情况下,您似乎正在处理排序假脱机文件等。
标签: django postgresql psycopg2 recursive-query