这是我的代码和成千上万的记录插入到表中但执行时间很长(大约15分钟),我该怎么做才能减少这个时间? 谢谢
BEGIN
delete from pre_percapita_accords t where t.dat_capit = DATACTUL;
FOR REC2 IN FORMUL_ID LOOP
FOR rec1 in FND_Bunit loop
FOR REClkp1 IN EMPLY(rec1.cod_busun,rec1.lkp_cod_dput_busun) LOOP
v_result_param1 := Fnd_Formula_Pkg.SET_PARAM_VALUE_FUN(REC2.FRML_ID,
'EMPL_ID',
to_char(REClkp1.num_prsn_emply));
v_result_param2 := Fnd_Formula_Pkg.SET_PARAM_VALUE_FUN(REC2.FRML_ID,
'DAT_ACCORD',
to_char(DATACTUL));
fnd_formula_set_param_prc(REC2.FRML_ID);
resultFun := Fnd_Formula_Pkg.GET_PARAM_VALUE_FUN(REC2.FRML_ID,
'NUM_RESULT');
resultFun := trunc(resultFun, 3);
if REClkp1.NUM_PRSN_EMPLY is not null and resultFun is not null and
DATACTUL is not null then
INSERT INTO pre_percapita_accords
(FRMLS_FORMUL_STEP_ID,
dat_capit,
num_capit,
emply_num_prsn_emply,
lkp_status_capit)
VALUES
(rec2.formul_step_id,
DATACTUL,
resultFun,
REClkp1.NUM_PRSN_EMPLY,
'3');
end if;
END LOOP;
END LOOP;
end loop;
答案 0 :(得分:1)
您有3个嵌套的游标循环,您可以在其中调用最低级别的多个函数并执行单行插入。这里有很多可能来改进:
1)函数Fnd_Formula_Pkg.SET_PARAM_VALUE_FUN被调用两次,但结果从未使用过(在您显示的代码中) - 这些调用可以简单地删除吗?
2)对Fnd_Formula_Pkg.SET_PARAM_VALUE_FUN的第二次调用不使用来自EMPLY或FND_Bunit游标的任何数据,因此可以将它移到这两个循环之外,从而导致它被调用得更少。
3)您可以将结果保存到数组中,然后使用例如批量插入一次1000行。
4)理想情况下,整个事物可以在没有游标的情况下重写为单个INSERT ... SELECT语句。我不能肯定地说这是可能的。
答案 1 :(得分:1)
您可以尝试使用sql trace and tkprof来获取更好的衡量标准,而不是猜测。我的猜测是函数调用很慢。
如果这看起来太令人生畏,你也可以通过添加一些时序日志语句(使用时间戳)进行调试,当然是针对dev db进行测试,并查看花费的时间(有点像旧的printf语句调试)。至少你会更好地了解大部分时间都在做什么。
答案 2 :(得分:0)