有多種方法可以提高更新的效率.
簡單說來:
1、暫停索引,更新后恢復.避免在更新的過程中涉及到索引的重建.
2、批量更新,每更新一些記錄后及時進行提交動作.避免大量占用回滾段和或臨時表空間.
3、創建一臨時的大的表空間用來應對這些更新動作.
=========================================================================不同看法
如果UPDATE的是索引字段,就會涉及到索引的重建,暫停索引不會提高多少的速度,反而有可能降低UPDATE速度,
因為在更新是索引可以提高數據的查詢速度,重建索引引起的速度降低影響不大。
ORACLE優化修改參數最多也只能把性能提高15%,大部分都是SQL語句的優化!
=========================================================================不同位置
update總體來說比insert要慢
幾點建議:
1、如果更新的數據量接近整個表,就不應該使用index而應該采用全表掃描
2、減少不必要的index,因為update表通常需要update index
3、如果你的服務器有多個cpu,采用parellel hint,可以大幅度的提高效率
前年我也遇到類似的問題,300萬紀錄的一個表,每天要全表更新20次左右,最初通過cursor多進程(18個進程)更新,耗時30分鐘,
后來采用full+parallel hint,耗時降低到3分鐘左右。服務器是ibm rs6000 s590,18個CPU,64GB內存。
另外,建表的參數非常重要,對于更新非常頻繁的表,建議加大PCTFREE的值,以保證數據塊中有足夠的空間用于UPDATE,
從而降低CHAINED_ROWS。
=========================================================================不同位置
如果有足夠CPU以及I/O 的話....
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ PARALLEL(tableA, 2) */
INTO tableA NOLOGGING
SELECT * FROM tableB;
當中的 2 是多少個進程同時執行. 可應不同情況加減.
=========================================================================不同位置
2比較可行的方法
方法一:使用oracle中包含在注釋中的提示信息
insert /*+append*/ into ...nologing
select * from ...
方法二:使用批量拷貝方法
set arraysize 20
set copycommit 5000
copy fromusername/password@oracle_nameappend table_name1
using select * from table_name2;
實際效果,方法一要比方法二速度還要快些
/*+append */ nologging 的方法不錯.
bulk insert好像需要內容足夠大才可以.
=========================================================================不同位置
set autocommit 100;----------每一百條記錄提交一次
set transaction use rollback segment RBS1;
INSERT INTO table1 NOLOGGING
SELECT * FROM table2;
commit;
改變表的存儲策略:
ALTER TABLE aaaa1
PCTFREE 30
PCTUSED 60;
---------這兩個值相加要小于100,把PCTFREE搞大,PCTUSED搞小,可能會快一點
=========================================================================不同位置
再提供一種方法,俺曾經用過的:
alter session set sort_area_size=100000000;
insert into tableb select * from tablea;
commit;
=========================================================================總結
提高更新速度總結:
1、暫停索引,更新后恢復.避免在更新的過程中涉及到索引的重建.
缺點:
如果UPDATE的是索引字段,就會涉及到索引的重建,暫停索引不會提高多少的速度,反而有可能降低UPDATE速度。
如果表比較龐大,停索引后重鍵需要花比較長的時間
優點:
如果更新的數據量接近整個表,此方法比較好。
2、批量更新,每更新一些記錄后及時進行提交動作.避免大量占用回滾段和或臨時表空間.
3、創建一臨時的大的表空間用來應對這些更新動作.
4、如果你的服務器有多個cpu,采用parellel hint,可以大幅度的提高效率
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ PARALLEL(tableA, 2) */INTO tableA NOLOGGING
SELECT * FROM tableB;
當中的 2 是多少個進程同時執行. 可應不同情況加減.
5、建表的參數非常重要,對于更新非常頻繁的表,建議加大PCTFREE的值,以保證數據塊中有足夠的空間用于UPDATE,從而降低CHAINED_ROWS
ALTER TABLE aaaa1
PCTFREE 30
PCTUSED 60;
---------這兩個值相加要小于100,把PCTFREE搞大,PCTUSED搞小,可能會快一點
6、oracle提示及批量拷貝
方法一:使用oracle中包含在注釋中的提示信息
insert /*+append*/ into ...nologing
select * from ...
方法二:使用批量拷貝方法
set arraysize 20
set copycommit 5000
copy fromusername/password@oracle_nameappend table_name1
using select * from table_name2;
實際效果,方法一要比方法二速度還要快些
7、加大排序緩沖區
alter session set sort_area_size=100000000;
insert into tableb select * from tablea;
commit;