很多人都认为使用直接加载可以大量减少redo的产生量,实际上直接加载并非在任何时候都能减少redo的产生。如果对象实在LOGGING模式下,直接加载并不能显著的减少日志量。看一个例子:
sys@ORCL> create table t
2 as
3 select * from dba_objects where 1=0;
Table created.
sys@ORCL> alter table t logging;
Table altered.
sys@ORCL> alter table t logging;
Table altered.
sys@ORCL>
sys@ORCL> set autotrace trace stat;
sys@ORCL> insert into t
2 select * from dba_objects whererownum<10000;
9999 rows created.
Statistics
----------------------------------------------------------
910 recursive calls
937 db block gets
2710 consistent gets
1 physical reads
1052484 redo size
924 bytes sent via SQL*Net toclient
973 bytes received via SQL*Netfrom client
6 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
9999 rows processed
sys@ORCL> rollback;
Rollback complete.
sys@ORCL> insert/*+append*/ into t
2 select * from dba_objects whererownum<10000;
9999 rows created.
Statistics
----------------------------------------------------------
40 recursive calls
139 db block gets
2283 consistent gets
28 physical reads
1030572 redo size
908 bytes sent via SQL*Net toclient
987 bytes received via SQL*Netfrom client
6 SQL*Net roundtrips to/fromclient
1 sorts (memory)
0 sorts (disk)
9999 rows processed
我们可以看到当表属性为LOGGING属性时,传统加载和直接加载所产生的redo量并没有很大的差别。主要原因是:当一个表为LOGGING属性时,即使是直接加载,所有改变的数据依然要差生redo,以便于以后的恢复,这时候直接加载并没有什么优势。
直接加载最常见是和NOLOGGING一起使用,这时候就能有效的减少redo量。例子:
sys@ORCL> rollback;
Rollback complete.
sys@ORCL> alter table t nologging;
Table altered.
sys@ORCL> insert/*+append*/ into t
2 select * from dba_objects whererownum<10000;
9999 rows created.
Statistics
----------------------------------------------------------
182 recursive calls
128 db block gets
2292 consistent gets
22 physical reads
588 redo size
908 bytes sent via SQL*Net toclient
987 bytes received via SQL*Netfrom client
6 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
9999 rows processed
在这种情况下直接加载的数据库不产生redo的,只有一些其他改变的数据产生一些redo,比如空间分配需要修改字典表或者修改段头数据块,这些修改会产生少量的redo.
由于在NOLOGGING下,redo不记录改变的数据,所以直接加载完后需要立即备份数据库,一旦数据损坏,只能使用备份来恢复。