如何使PL / SQL执行得更快

时间:2017-08-30 11:44:09

标签: oracle plsql

我有这个PL / SQL程序,运行大约4-6分钟:

DECLARE
     i NUMBER := 0;
     begin
     for x in (select     anumber
               ,          position
               ,          character
               from       sdc_positions_cip
               where      kind = 'Name')
loop    
    update sdc_compare_person dcip
    set dcip.GESNAM_D = substr(dcip.GESNAM_D, 1, x.position - 1) || x.character || 
    substr(dcip.GESNAM_D, x.position + 1, length(dcip.GESNAM_D) - x.position)
    where dcip.sourcekey = x.anumber;

    i := i + 1;
    IF i > 100 THEN COMMIT;
    i := 0;
    END IF;
end loop;
commit;
end;
/

我在dcip.sourcekeyx.anumber上放了一个索引。 它使用的表空间是10GB。

有没有办法让这个程序(更多)更快?

2 个答案:

答案 0 :(得分:10)

您的性能瓶颈就是循环。它强制您的代码在每个UPDATE - 语句的PLSQL和Oracle SQL之间切换。

为了消除这些上下文切换,您可以使用UPDATE - 包含子选择的语句,但我更喜欢MERGE,例如,如下所示:

merge into sdc_compare_person dcip
using (
    select anumber, position, character
    from sdc_positions_cip
    where kind = 'Name'
) x
on (dcip.sourcekey = x.anumber)
when matched then update set
    dcip.GESNAM_D = substr(dcip.GESNAM_D, 1, x.position - 1) ||
    x.character ||
    substr(dcip.GESNAM_D, x.position + 1, length(dcip.GESNAM_D) - x.position);

另一种选择是使用BULK COLLECT INTOFORALL来执行批量选择和批量插入。由于您的程序复杂性有限,我强烈建议您使用像我这样的单一陈述。

答案 1 :(得分:1)

您也可以尝试此版本:

update 
   (select dcip.GESNAM_D, x.position, x.character, dcip.sourcekey, anumber
    from sdc_compare_person dcip
       join sdc_positions_cip on dcip.sourcekey = x.anumber)
set GESNAM_D = substr(GESNAM_D, 1, position - 1) || character || substr(GESNAM_D, position + 1, length(GESNAM_D) - position);