转载-insert /*+ append */

文章出处:http://www.cnblogs.com/sopost/archive/2012/11/23/2785270.html

总结得出以下3点结论:
a
、非归档模式下,只需append就能大量减少redo的产生;归档模式下,只有append+nologging才能大量减少redo
b

总结得出以下3点结论:
a
、非归档模式下,只需append就能大量减少redo的产生;归档模式下,只有append+nologging才能大量减少redo
b
insert /*+ append */ 时会对表加锁(排它锁),会阻塞表上的除了select以外所有DML语句;传统的DMLTM enqueue上使用模式3row exclusive),其允许其他DML在相同的模式上获得TM enqueue。但是直接路径加载在TM enqueue使用模式6exclusive),这使其他DML在直接路径加载期间将被阻塞。
c
insert /*+ append */ 直接路径加载,速度比常规加载方式快。因为是从HWM的位置开始插入,也许会造成空间浪费。


数据库版本:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL 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
当前日志序列           97

1nologging
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

2logging表:
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 mount
ORACLE
例程已经启动。

Total System Global Area  477073408 bytes
Fixed Size                  1337324 bytes
Variable Size             293603348 bytes
Database Buffers          176160768 bytes
Redo Buffers                5971968 bytes
数据库装载完毕。
SQL> alter database archivelog;
数据库已更改。

SQL> alter database open;
数据库已更改。

SQL> archive log list
数据库日志模式            存档模式
自动存档             启用
存档终点            USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列
     95
下一个存档日志序列
   97
当前日志序列           97

1nologging
SQL> select * from redo_size;
    
VALUE
----------
     17936

SQL> 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

2logging
SQL> select * from redo_size;
     VALUE
----------
   8506780

SQL> 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(*)
----------
    291016

SQL> 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 immediate
ORA-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全部阻塞。

 时会对表加锁(排它锁),会阻塞表上的除了 select以外所有 DML语句;传统的 DMLTM enqueue上使用模式 3row exclusive),其允许其他 DML在相同的模式上获得 TM enqueue。但是直接路径加载在 TM enqueue使用模式 6exclusive),这使其他 DML在直接路径加载期间将被阻塞。
c
insert /*+ append */ 直接路径加载,速度比常规加载方式快。因为是从HWM的位置开始插入,也许会造成空间浪费。


数据库版本:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL 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
当前日志序列           97

1nologging
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

2logging表:
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 mount
ORACLE
例程已经启动。

Total System Global Area  477073408 bytes
Fixed Size                  1337324 bytes
Variable Size             293603348 bytes
Database Buffers          176160768 bytes
Redo Buffers                5971968 bytes
数据库装载完毕。
SQL> alter database archivelog;
数据库已更改。

SQL> alter database open;
数据库已更改。

SQL> archive log list
数据库日志模式            存档模式
自动存档             启用
存档终点            USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列
     95
下一个存档日志序列
   97
当前日志序列           97

1nologging
SQL> select * from redo_size;
    
VALUE
----------
     17936

SQL> 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

2logging
SQL> select * from redo_size;
     VALUE
----------
   8506780

SQL> 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(*)
----------
    291016

SQL> 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 immediate
ORA-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全部阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值