使用BULK COLLECT+FORALL加速批量提交

1、        批量提交

批量提交特色:

佔用較少undo,資源(獨佔鎖,undo)快速釋放,執行時間長web

批量提交適合場景:

在線大批量插入,更新,刪除數據sql

2、        BULK COLLECT+FORALL性能提高

1.經過BULK COLLECT加速查詢

無論是顯示遊標仍是隱式遊標,均可以經過BULK COLLECT在數據庫的單次交互中獲取多行數據。BULKCOLLECT相對Cursor Loop方式減小了PL/SQL引擎和SQL引擎之間的切換次數,所以也減小了提取數據時的額外開銷。
數據庫

經過LIMIT rows限制提取的記錄數

這種方法會減小對PGA的消耗,避免換頁產生app

3經過FORALL 加速DML

FORALL告訴PL/SQL引擎要先把一個或多個集合的全部成員都綁定到SQL語句中,而後再把語句發送給SQL引擎若是for ..loop 循環,那麼會發送n(循環的次數)次,而用Forall,一次行所有發送過去。
oop

3、        BULK COLLECT + FORALL 批量提交例句

insert

declare
  TYPE ARRAY IS TABLE OF big_table%ROWTYPE;
  l_data ARRAY;
  CURSOR c IS
    SELECT * FROM big_table;
BEGIN
  OPEN c;
  LOOP
    FETCH c BULK COLLECT
      INTO l_data LIMIT 5000;
  
    FORALL i IN 1 .. l_data.COUNT
      INSERT /*+append*/
      INTO big_table
      VALUES l_data
        (i);
    commit;
    EXIT WHEN c%NOTFOUND;
  END LOOP;
  CLOSE c;

delete

DECLARE
  CURSOR mycursor IS
    SELECT rowid FROM t WHERE OO = XX;
  TYPE rowid_table_type IS TABLE OF rowid index by pls_integer;
  v_rowid rowid_table_type;
BEGIN
  OPEN mycursor;
  LOOP
    FETCH mycursor BULK COLLECT
      INTO v_rowid LIMIT 5000;
    EXIT WHEN v_rowid.count = 0;
    FORALL i IN v_rowid.FIRST .. v_rowid.LAST
      DELETE t WHERE rowid = v_rowid(i);
    COMMIT;
  END LOOP;
  CLOSE mycursor;
END;

update

DECLARE
  CURSOR mycursor IS
    SELECT t_pk FROM t WHERE OO = XX;
  TYPE num_tab_t IS TABLE OF NUMBER(38);
  pk_tab NUM_TAB_T;
BEGIN
  OPEN mycursor;
  LOOP
    FETCH mycursor BULK COLLECT
      INTO pk_tab LIMIT 5000;
    EXIT WHEN pk_tab.count = 0;
    FORALL i IN pk_tab.FIRST .. v_rowid.LAST
      UPDATE t SET name = name || ’bulk’ WHERE t_pk = pk_tab(i);
    COMMIT;
  END LOOP;
  CLOSE mycursor;
END;
相關文章
相關標籤/搜索