我有这个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.sourcekey
和x.anumber
上放了一个索引。
它使用的表空间是10GB。
有没有办法让这个程序(更多)更快?
答案 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 INTO
和FORALL
来执行批量选择和批量插入。由于您的程序复杂性有限,我强烈建议您使用像我这样的单一陈述。
答案 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);