postgresql游标更新速度很慢

时间:2013-06-21 15:32:34

标签: postgresql paraccel

作为简短的前言,我是postgresql的新手。另外,我需要建议的postgresql版本是8.1。原因是postgresql 8.1是ParAccel最后一次实现和支持该语言的版本。

Postgresql游标,至少在8.1中,使用DML操作非常慢,例如UPDATE或INSERT(未测试DELETE,但假设它是相同的)。这只是一个展示的例子:

create table tab_cur_DML_test (col_key int,col_dml varchar(50));

用一些表中的一些记录填充它:

insert into tab_cur_DML_test (col_key, col_dml)
select card_id, card_no
from card_dim;

tab_cur_DML_test现在只有几千条记录,只有两个字段

create or replace function fn_cursor_DML_test() returns void as
$body$
declare
    v_col_key                   card_dim.card_id%type;
    v_col_dml                   card_dim.card_no%type;
    cur                     refcursor;
    v_count_proccessed_recs         bigint := 0 ;
begin
    open cur for select card_id, card_no from card_dim;
    loop
        fetch cur into v_col_key, v_col_dml;
        if not found then exit; end if;

        update tab_cur_DML_test
        set col_dml = v_col_dml
        where col_key = v_col_key;

        v_count_proccessed_recs := v_count_proccessed_recs + 1;

        if v_count_proccessed_recs%10 = 0 then
                raise info '%', v_count_proccessed_recs;
        end if;
    end loop;

end;
$body$
language plpgsql volatile;

运行后:

select * from fn_cursor_DML_test();

速度达到每30秒约一千条记录。

同样,这只是一个简单的更新,可以作为基于集合的操作来完成。我在这里用它来模拟用光标进行逐行处理。在类似的实际任务情况下,当需要逐行处理时,在使用普通sql的情况下不会这样做,否则,将太笨重和/或复杂,使用具有如此低处理速度的光标变得不可行。

我怀疑这是由于数据库引擎中的上下文切换而发生的。我的问题是有没有可能的解决方法(或者只是某种方式)来显着改进postgresql 8.1游标中的逐行逻辑,如果这很重要 - 在ParAccel(v.4.0)中?

谢谢!

斯坦尼斯

1 个答案:

答案 0 :(得分:2)

ParAccel不是PostgreSQL。这是两种不同的产品,具有为不同目的设计的不同功能。 ParAccel基于PostgreSQL,但它利用柱状存储,MPP和优化器完全重写。碰巧他们保留了PL扩展(在某些情况下最有可能是为了缓解ETL的编排),但他们放弃了支持。像Vertica这样的其他竞争对手 - 甚至在他们的产品中都没有pgPL扩展。

您遇到的症状与PostgreSQL无关。这就是ParAccel不支持pgPL / SQL解析器的确切原因。数据库不是为逐行处理而设计的,因为它是柱状的。单个更新/插入/删除将占用与在数百万行上执行相同操作一样多的资源。为什么你需要在这里使用PL?只需运行更新。 ...并阅读有关柱状数据库的更多信息。如果您需要逐行操作并且没有多少选择,ParAccel不是您需要的正确产品。

http://en.wikipedia.org/wiki/Column-oriented_DBMS
http://www.paraccel.com/resources/resources-2.php#.UdNv0m024V0