总结得出以下3点结论:
a、非归档模式下,只需append就能大量减少redo的产生;归档模式下,只有append+nologging才能大量减少redo。b、insert /*+ append */ 时会对表加锁(排它锁),会阻塞表上的除了select以外所有DML语句;传统的DML在TM enqueue上使用模式3(row exclusive),其允许其他DML在相同的模式上获得TM enqueue。但是直接路径加载在TM enqueue使用模式6(exclusive),这使其他DML在直接路径加载期间将被阻塞。c、insert /*+ append */ 直接路径加载,速度比常规加载方式快。因为是从HWM的位置开始插入,也许会造成空间浪费。 数据库版本:SQL> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionPL/SQL Release 11.2.0.1.0 - ProductionCORE 11.2.0.1.0 ProductionTNS for Linux: Version 11.2.0.1.0 - ProductionNLSRTL Version 11.2.0.1.0 - Production网上说测试时不要使用auto trace来查看redo size,这个值是有偏差的.建议建立一个视图:
SQL> create or replace view redo_size 2 as 3 select value 4 from v$mystat, v$statname 5 where v$mystat.statistic# = v$statname.statistic# 6 and v$statname.name = 'redo size';视图已创建。一、非归档模式
SQL> archive log list数据库日志模式 非存档模式自动存档 禁用存档终点 USE_DB_RECOVERY_FILE_DEST最早的联机日志序列 95当前日志序列 971、nologging表
SQL> create table test1 nologging as select * from dba_objects where 1=0;表已创建。SQL> select * from redo_size; VALUE---------- 25714940
SQL> insert into test1 select * from dba_objects;已创建72753行。
SQL> select * from redo_size; VALUE---------- 34216916
SQL> insert /*+ APPEND */ into test1 select * from dba_objects;已创建72753行。
SQL> select * from redo_size; VALUE---------- 34231736
SQL> select (34231736-34216916) redo_append , (34216916-25714940) redo_normal from dual;REDO_APPEND REDO_NORMAL----------- ----------- 14820 8501976
2、logging表:
SQL> create table test2 as select * from dba_objects where 1=0;表已创建。
SQL> select * from redo_size; VALUE---------- 34273348
SQL> insert into test2 select * from dba_objects;
已创建72754行。
SQL> select * from redo_size; VALUE---------- 42775336
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;已创建72754行。
SQL> select * from redo_size; VALUE---------- 42790156
SQL> select (42790156-42775336) redo_append , (42775336-34273348) redo_normal from dual;REDO_APPEND REDO_NORMAL----------- ----------- 14820 8501988
二、归档模式下:
SQL> shutdown immediate数据库已经关闭。
已经卸载数据库。ORACLE例程已经关闭。SQL> startup mountORACLE例程已经启动。Total System Global Area 477073408 bytesFixed Size 1337324 bytesVariable Size 293603348 bytesDatabase Buffers 176160768 bytesRedo Buffers 5971968 bytes数据库装载完毕。
SQL> alter database archivelog;数据库已更改。SQL> alter database open;数据库已更改。
SQL> archive log list数据库日志模式 存档模式
自动存档 启用存档终点 USE_DB_RECOVERY_FILE_DEST最早的联机日志序列 95下一个存档日志序列 97当前日志序列 971、nologging表
SQL> select * from redo_size; VALUE---------- 17936SQL> insert into test1 select * from dba_objects;已创建72754行。
SQL> select * from redo_size; VALUE---------- 8490972
SQL> insert /*+ APPEND */ into test1 select * from dba_objects;已创建72754行。
SQL> select * from redo_size; VALUE---------- 8506164
SQL> select (8506164-8490972) redo_append , (8490972-17936) redo_normal from dual;REDO_APPEND REDO_NORMAL----------- ----------- 15192 8473036
2、logging表
SQL> select * from redo_size; VALUE---------- 8506780SQL> insert into test2 select * from dba_objects;已创建72754行。
SQL> select * from redo_size; VALUE---------- 16979516
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;已创建72754行。
SQL> select * from redo_size; VALUE---------- 25518172
SQL> select (25518172-16979516) redo_append , (16979516-8506780) redo_normal from dual;REDO_APPEND REDO_NORMAL----------- ----------- 8538656 8472736
在归档模式下,对于常规表的insert append产生和insert同样的redo此时的insert append实际上并不会有性能提高.但是此时的append是生效了的。
三、insert /*+ append */会阻塞除select以外的DML语句,direct-path insert操作是单独一个事务。SQL> select count(*) from test2; COUNT(*)---------- 291016SQL> insert into test2 select * from dba_objects;已创建72754行。
SQL> select count(*) from test2; COUNT(*)---------- 363770
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;已创建72754行
同一个session下:
SQL> select count(*) from test2;select count(*) from test2*第 1 行出现错误:ORA-12838: 无法在并行模式下修改之后读/修改对象
SQL> commit;提交完成。
SQL> select count(*) from test2; COUNT(*)---------- 436524
SQL> insert /*+ APPEND */ into test2 select * from dba_objects;已创建72754行。
SQL> shutdown immediateORA-01097: 无法在事务处理过程中关闭 - 请首先提交或回退
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
---------- ---------- ----------
224 0 1
SQL> select KADDR,TYPE,LMODE from v$lock where sid=224;
KADDR TY LMODE
---------------- -- ----------
0000000071BAE180 TM 6
0000000070CB11B8 TX 6
另外开启一个会话,就会发现只能select,其他DML全部阻塞。
转载