2017-06-14 24 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)を設定します。 – tale852150

答えて

4

同等の純粋なSQL文:

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

これはおそらく、あなたの手続きバージョンよりも高速に実行されます。 PL/SQLのバルク処理は行単位よりも高速ですが、通常は単一の集合単位操作よりも処理速度が遅くなります。手続き的にしか扱うことができない複雑な変換ロジックがある時は、その時間を節約してください。

+0

ありがとう! – Shin