问题描述
嗨,汤姆,
跟随循环是我在live系统中最大的问题。以下循环将每天运行,以在OLTP系统中插入600万多个记录,并花费20个小时。在记忆方面,我们没有任何问题。
6TB of memory
195 CPU cores
2.5 GHz cpu speed
Intel Xeon E5-4640 CPU Type
以下是代码: 您能帮助我如何加快以下循环吗?
开始
打开卷 _ 企业社会责任;
循环
获取rollup_csr批量收集到v_csr_tab限制100;
当v_csr_tab.COUNT = 0时退出;
开始
第一个 .. v_csr_tab.count保存异常
插入blahblah
(create_date,test1,test2,test3,test4,
测试5,测试6,测试7,
测试8、测试9、测试10、测试11、测试12)
值
(v_run_date,
v_csr_tab(i)。test1,v_csr_tab(i)。test2,
v_csr_tab(i).test3,v_csr_tab(i).test4,
v_csr_tab(i).test5,v_csr_tab(i).test6,
v_csr_tab(i).test7,v_csr_tab(i).test8,v_csr_tab(i).test9,
v_csr_tab(i).test10/v_cnt,v_csr_tab(i).test11/v_cnt,(v_csr_tab(i).test11/v_cnt) / (v_csr_tab(i).test10 / v_cnt)) * 100)
);
异常
当dml_errors时
null;
当其他人那么
v_err_code := SQLCODE;
v_err_msg := SUBSTR(SQLERRM,1,250);
插入error_table
(err_num,err_msg,模块,create_dtm)
值
(v_err_code,v_err_msg,'插入-blahblah',sysdate);
结束;
提交;
结束循环;
关闭卷 _ csr;
结束;
结束;
/
非常感谢。
迈克
跟随循环是我在live系统中最大的问题。以下循环将每天运行,以在OLTP系统中插入600万多个记录,并花费20个小时。在记忆方面,我们没有任何问题。
6TB of memory
195 CPU cores
2.5 GHz cpu speed
Intel Xeon E5-4640 CPU Type
以下是代码: 您能帮助我如何加快以下循环吗?
开始
打开卷 _ 企业社会责任;
循环
获取rollup_csr批量收集到v_csr_tab限制100;
当v_csr_tab.COUNT = 0时退出;
开始
第一个 .. v_csr_tab.count保存异常
插入blahblah
(create_date,test1,test2,test3,test4,
测试5,测试6,测试7,
测试8、测试9、测试10、测试11、测试12)
值
(v_run_date,
v_csr_tab(i)。test1,v_csr_tab(i)。test2,
v_csr_tab(i).test3,v_csr_tab(i).test4,
v_csr_tab(i).test5,v_csr_tab(i).test6,
v_csr_tab(i).test7,v_csr_tab(i).test8,v_csr_tab(i).test9,
v_csr_tab(i).test10/v_cnt,v_csr_tab(i).test11/v_cnt,(v_csr_tab(i).test11/v_cnt) / (v_csr_tab(i).test10 / v_cnt)) * 100)
);
异常
当dml_errors时
null;
当其他人那么
v_err_code := SQLCODE;
v_err_msg := SUBSTR(SQLERRM,1,250);
插入error_table
(err_num,err_msg,模块,create_dtm)
值
(v_err_code,v_err_msg,'插入-blahblah',sysdate);
结束;
提交;
结束循环;
关闭卷 _ csr;
结束;
结束;
/
非常感谢。
迈克
专家解答
您没有代码问题,您有设计或SQL性能问题。
这是我的笔记本电脑几乎使用了您的代码,在12秒内插入了500万行
所以你的20小时意味着
-您打开的游标是执行起来非常昂贵的SQL,或者
-插入目标表的内容正在杀死插入速度,例如太多的索引,触发器等
因此,为每个阶段添加一些时间,并可能使用以下方法进行一些跟踪:
dbms_monitor.session_trace_enable
看看时间在哪里丢失。
从性能角度来看,您的 * 代码 * 很好 (但也可以查看 “DML错误日志记录”)
这是我的笔记本电脑几乎使用了您的代码,在12秒内插入了500万行
SQL> create table t as select s.* from dba_source s, 2 ( select 1 from dual connect by level <= 10 ); Table created. SQL> SQL> select count(*) from t; COUNT(*) ---------- 5058450 1 row selected. SQL> SQL> create table t1 as select * from t where 1=0; Table created. SQL> SQL> set timing on SQL> declare 2 cursor rollup_csr is select * from t; 3 type row_list is table of t%rowtype index by pls_integer; 4 v_csr_tab row_list; 5 BEGIN 6 OPEN rollup_csr; 7 LOOP 8 FETCH rollup_csr BULK COLLECT INTO v_csr_tab LIMIT 100; 9 EXIT WHEN v_csr_tab.COUNT = 0; 10 BEGIN 11 12 FORALL i in v_csr_tab.FIRST..v_csr_tab.count save exceptions 13 INSERT INTO t1 values v_csr_tab(i); 14 END; 15 COMMIT; 16 END LOOP; 17 18 CLOSE rollup_csr; 19 END; 20 / PL/SQL procedure successfully completed. Elapsed: 00:00:12.33
所以你的20小时意味着
-您打开的游标是执行起来非常昂贵的SQL,或者
-插入目标表的内容正在杀死插入速度,例如太多的索引,触发器等
因此,为每个阶段添加一些时间,并可能使用以下方法进行一些跟踪:
dbms_monitor.session_trace_enable
看看时间在哪里丢失。
从性能角度来看,您的 * 代码 * 很好 (但也可以查看 “DML错误日志记录”)
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




