如何在多次记录时减少插入数据库的时间?

时间:2011-02-22 08:26:28

标签: plsql

这是我的代码和成千上万的记录插入到表中但执行时间很长(大约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;

3 个答案:

答案 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)