2017-06-14 217 views
0

我有这个plsql脚本。我能够在大约300行的测试台上测试它,并且它工作得很好。但是,当我尝试使用大约1M行的实际表来运行它时,它并未完成。我想就如何优化我的脚本寻求您的建议,我是plsql的新手,所以任何想法/建议都非常有帮助。 :)PLSQL脚本优化/调优

DECLARE 
    c_BGROUP PP_TRANCHE_RBS.BGROUP%TYPE := 'RBS'; 
    l_start  NUMBER; 

    /* Check for all entries where pt03d = pt04d+1. */ 
    CURSOR c_pp_tranche IS 
     SELECT 
      refno, 
      pt04d, 
      seqno 
     FROM PP_TRANCHE_RBS a 
     WHERE a.BGROUP = c_BGROUP 
     AND a.pt03d = (SELECT (pt04d + 1) 
         FROM PP_TRANCHE_RBS 
         WHERE bgroup = a.bgroup 
         AND refno = a.refno 
         and seqno = a.seqno) 
    ; 

    TYPE c_refno IS TABLE OF PP_TRANCHE_RBS.REFNO%TYPE; 
    TYPE c_pt04d IS TABLE OF PP_TRANCHE_RBS.PT04D%TYPE; 
    TYPE c_seqno IS TABLE OF PP_TRANCHE_RBS.SEQNO%TYPE; 

    t_refno c_refno; 
    t_pt04d c_pt04d; 
    t_seqno c_seqno; 

BEGIN 

    DBMS_OUTPUT.put_line('Updating rows... '); 

    l_start := DBMS_UTILITY.get_time; 

    OPEN c_pp_tranche; 
    LOOP 

     FETCH c_pp_tranche BULK COLLECT INTO t_refno, t_pt04d, t_seqno LIMIT 10000; -- break the data into chucks of 10000 rows 
     EXIT WHEN t_refno.COUNT() = 0; -- cursor attribute to exit when 0. 

     FORALL i IN t_refno.FIRST .. t_refno.LAST 

      /* Update pt03d = pt04d */ 
      UPDATE PP_TRANCHE_RBS 
      SET pt03d = t_pt04d(i) 
      WHERE 
       bgroup = c_BGROUP 
       AND refno = t_refno(i) 
       AND seqno = t_seqno(i) 
      ; 

     -- Process contents of collection here. 
     DBMS_OUTPUT.put_line(t_refno.count || ' rows was updated');  

    END LOOP; 

     DBMS_OUTPUT.put_line('Bulk Updates Time: ' || (DBMS_UTILITY.get_time - l_start)); 

    CLOSE c_pp_tranche; 
END; 
/

exit; 
+0

任何错误消息?你的DBMS_OUTPUT.put_line()调用的价值是什么? – tale852150

+0

没有错误信息或任何输出:( – Shin

+0

没有为DBMS_OUTPUT.put_line(t_refno.count ||'rows was updated'); ??设置dbms_output.enable(NULL);在你的代码开始。运行这个通过SQLPlus也运行* set serveroutput on *之前运行您的代码 – tale852150

回答

4

的当量纯SQL语句:

UPDATE PP_TRANCHE_RBS 
    SET pt03d = pt04d 
    WHERE bgroup = 'RBS' 
    and pt03d = pt04d + 1; 

这可能会跑的比你的程序的版本速度更快。 PL/SQL批量处理比逐行更快,但通常比单个基于集的操作要慢。因此,如果您的复杂转换逻辑只能在程序上处理,那么就保存它。

+0

感谢您的支持! – Shin