【发布时间】:2015-03-11 22:12:35
【问题描述】:
我正在将 python 代码重写为 plpgsql,它对表进行切片并将表的切片导入回数据库到不同的表中。假设Func(..) 是一个返回一些INT 的函数
Condition(..., ...) 是一些条件表达式。
Python
- copy_expert
COPY (SELECT *, (Func(B)) FROM TABLE A ORDER BY (SELECT Func(B) FROM B WHERE Condition(A,B)) TO STDOUT到文件 - 通过写入不同的转储切片文件,在 python 中将结果表切片为
n部分 - 为每个切片获取一个新游标并运行 copy_expert
COPY some_table FROM STDIN
PL/Pgsql
-
运行类似的东西
DECLARE ... part_name VARCHAR[] = ARRAY[{part_names}]; prep_stmt VARCHAR[] = ARRAY[{parts}]; BEGIN FOR i in 1..{parts} LOOP prep_stmt[i] := $$ INSERT INTO $$ || part_name[i] || $$ ({list_cols}) VALUES ({args}); $$; END LOOP; FOR row IN (SELECT *, (Func(B)) FROM TABLE A ORDER BY (SELECT Func(B) FROM B WHERE Condition(A,B)) LOOP chosen_part := 0; FOR i IN 1..{parts} LOOP -- choose some part based on Func(B) -- this takes negligible amount of time ... END LOOP; EXECUTE prep_stmt[part] USING row; END LOOP; END
Python 方法可以更快地执行此任务。我的意思是速度要快几个数量级,尽管客户端和数据库是不同的机器。桌子
有~16M 行,每行有5-7 列。
有没有办法使用 plpgsql 让它运行得更快?
上下文
然后,切片将保留在一台机器上,并使用不同的光标和每个处理器进行处理。切片的原因是进一步的处理是CPU 而不是IO 密集型,因为它与多边形交集一起使用,切片带来了显着的性能优势(至少对于非切片实现而言)
编辑
我真的更喜欢实际回答问题的答案,而不是提出该方法是错误的。有时糟糕的设计会阻止轻松改变方法,这可能就是这种情况。问题是为什么 python 方法更快以及如何使 plpgsql 方法更快。
编辑 2
是否可以说WRITE TO FILE ...而不是INSERT ...,然后最后批量加载?
编辑 3
我想重申,设置是我无法避免将切片创建为单独的表。
我不能为每个切片说 CREATE TABLE AS 的原因是因为
我正在根据FUNC(B) 的输出为A 中的每一行“平衡”切片。该方法试图模仿min-make-span 问题。在CREATE TABLE AS 内不可能做这样的事情。
可能的解决方案:
这是我偶然发现的可能是解决方案的列表,你知道其他人吗?
- DBLINK 扩展以在单独的连接中插入每个切片?
- 先写入未记录的临时表,然后导入切片
【问题讨论】:
-
为什么要对表进行切片?一些上下文会给你更好的答案。
-
@JonClements 我想在之后并行处理每个切片
-
“并行”是什么意思?
-
@JonClements “并行”我的意思是对每个切片和不同的处理器使用不同的光标
-
对不起 - 只是忍不住觉得这是一个 XY 问题...
标签: python postgresql plpgsql