我正在将python代码重写为plpgsql,用于切片表并将表的切片导回到数据库中的不同表中。假设Func(..)
是一个返回一些INT
的函数
Condition(..., ...)
是一些条件表达式。
COPY (SELECT *, (Func(B)) FROM TABLE A ORDER BY (SELECT Func(B) FROM B WHERE Condition(A,B)) TO STDOUT
到文件n
部分COPY some_table FROM STDIN
运行类似
的内容 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方法更快。
是否可以说WRITE TO FILE ...
而不是INSERT ...
,然后最后批量加载?
我想重申一下,我无法避免将切片创建为单独的表格。
我不能为每个切片说CREATE TABLE AS
的原因是因为
我是平衡"基于FUNC(B)
输出的A
中每行的切片。该方法试图模仿min-make-span
问题。在CREATE TABLE AS
内无法做到类似的事情。
以下是我偶然发现的可能是解决方案的清单,您是否了解其他人?
答案 0 :(得分:0)
问题是为什么python接近更快以及如何制作 plpgsql的处理速度更快。
这不是由于Python,而是COPY
与INSERT
。使用COPY
批量加载 比使用INSERT
做同样快。
除此之外,您的查询似乎没有意义:
SELECT *, (Func(B))
FROM TABLE A
ORDER BY (SELECT Func(B) FROM B WHERE Condition(A,B)
多种方式在语法上无效。基于此,很难说出任何话。
只要你住在同一个数据库中,我的第一个想法就是CREATE TABLE AS
:
CREATE TABLE slice_n AS
SELECT col1, col2, ...
FROM big_table
ORDER BY whatever -- cluster data while being at it
WHERE whatever;
根据所提供的信息,不能说更多 克雷格收集了一份一般性建议清单: