我正在尝试使用这段代码,但它需要几个小时才能运行:
create table tmp$_mkemp_2 (id number generated by default on null as identity primary key, c1 varchar2 (30), c2 varchar2 (30))
/
set timing on serveroutput on size unlimited linesize 32767 pagesize 50000 trimspool on tab off feedback on heading on verify on
define svTableName = tmp$_mkemp_2
define svInsertHowMany = 500000
define svFetchRate = 2000
define svUpdateWhichMod = 2
define svDeleteWhichMod = 10
col ts format a20
col cnt format a10
<<s01_row_by_row_rbr_dml>> begin <<rbr_loop>> for iRec in (select dbms_random.string ('p', 10) c1, level id from dual connect by level <= &svInsertHowMany) loop
insert into &svTableName (c1) values (iRec.c1);
if mod (iRec.id, &svFetchRate) = 0 then commit; end if; end loop rbr_loop; commit;
<<update_loop>> for iUpdateRec in (select id, c1 from &svTableName) loop
update &svTableName set c2 = substr (c1, 1, 2) || ' ## ' || id where mod (id, &svUpdateWhichMod) = 0 and id = iUpdateRec.id;
if mod (iUpdateRec.id, &svFetchRate) = 0 then commit; end if; end loop update_loop; commit;
<<delete_loop>> for iDeleteRec in (select id, c1 from &svTableName) loop
delete &svTableName where id = iDeleteRec.id and mod (iDeleteRec.id, &svDeleteWhichMod) = 0;
if mod (iDeleteRec.id, &svFetchRate) = 0 then commit; end if; end loop delete_loop; commit;
end s01_row_by_row_rbr_dml;
/
select to_char (sysdate, 'mm/dd/yyyy hh24:mi:ss') ts from dual
/
select count (0) cnt from &svTableName
/
字符串
当我从另一个会话中检查表计数时,它显示450,000,这意味着delete_loop
已经完成。这需要大约10分钟,* 但该过程在那之后继续运行数小时 *。
为什么工作完成后,原始会话中的事务仍在继续运行?
这个问题在较小的数据集上似乎是可以重现的。例如,对于50,000行,删除大约在1分钟后完成(表现在显示为有45,000行),但整个过程需要6分钟才能完成。
我知道这是一种错误的数据处理方法,但我想了解这种方法的运行时性能的细节。
1条答案
按热度按时间neskvpey1#
这一行代码:
字符串
循环了50万次。在每个循环中,你都在做一个单独的删除操作,你唯一的 predicate 是一个取模函数。你是否省略了
and id = iDeleteRec.id
predicate 来镜像你为更新所做的事情?当前代码删除的内容超出了您的预期,而且无法使用索引来执行此操作。