Oracle 10g大表批次更新最佳化

來源:互聯網
上載者:User

Oracle 10g大表批次更新最佳化,其實,700萬的表不算大表,作為測試夠了

一,t表資訊
SQL> alter table t add is_del number(1);
SQL> alter table t modify is_del default 0;

SQL> desc t
Name   Type      Nullable Default Comments
------ --------- -------- ------- --------
ID     NUMBER    Y                       
CODE   NUMBER    Y                       
IS_DEL NUMBER(1) Y        0

SQL> select count(*) from t;
 
  COUNT(*)
----------
  7136976

二,為了比較基準的一致性,先緩衝t資料
update t set t.is_del = 0;

三,這裡共總結了4種方法
SQL> set timing on
--0
SQL> update t set t.is_del = 0;

7136976 rows updated.

Elapsed: 00:08:28.64

--1
SQL> declare
  2    rnt pls_integer := 0;
  3  begin
  4    for idx in (select rowid rid from t) loop
  5      update t set t.is_del = 0 where rowid = idx.rid;
  6      rnt := rnt + 1;
  7      if mod(rnt,2000) = 0 then
  8        commit;
  9      end if;
 10    end loop;
 11    commit;
 12  end;
 13  /

PL/SQL procedure successfully completed.

Elapsed: 00:09:41.32
SQL>

--2
SQL> declare
  2    rnt pls_integer := 0;
  3  begin
  4    for idx in (select rowid rid from t) loop
  5      update t set t.is_del = 0 where rowid = idx.rid;
  6      rnt := rnt + 1;
  7      if rnt = 2000 then
  8        rnt := 0;
  9        commit;
 10      end if;
 11    end loop;
 12    commit;
 13  end;
 14  /

PL/SQL procedure successfully completed.

Elapsed: 00:09:35.67

--3
SQL> declare
  2    cursor cur_t is select rowid rid from t;
  3    type tab_t is table of urowid index by binary_integer;
  4    l_rid tab_t;
  5  begin
  6    open cur_t;
  7    loop
  8      fetch cur_t bulk collect into l_rid limit 2000;
  9      forall idx in 1 .. l_rid.count
 10        update t set t.is_del = 0 where rowid = l_rid(idx);
 11      commit;
 12      exit when cur_t%notfound;
 13    end loop;
 14    close cur_t;
 15  end;
 16  /

PL/SQL procedure successfully completed.

Elapsed: 00:06:48.84

通過上面的測試結果可以看到,方法3最好,方法0不建議使用,這會使undo快速增長,出現ora-01555錯誤。方法1和方法2在一些書籍上看到過測試,說方法2優於方法1,但我這次測試效果不明顯,以後再進行一些測試。

註:
測試的資料庫配置了閃回特性,db_recovery_file_dest_size=2g,歸檔日誌放在db_recovery_file_dest目錄中。開始時的更新操作,redo增長很快,常常hang住了,alert log報空間不足,所有增加了db_recovery_file_dest_size=4g。還有要注意undo資料表空間的監控。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.