append小结

来源:互联网 发布:js原型和原型链面试题 编辑:程序博客网 时间:2024/06/07 12:54

 Hint:  append小结

The APPEND hint lets you enable direct-path INSERT if your database is running in serial mode. Your database is in serial mode if you are not using Enterprise Edition. Conventional INSERT is the default in serial mode, and direct-path INSERT is the default in parallel mode.
In direct-path INSERT, data is appended to the end of the table, rather than using existing space  currently allocated to the table. As a result, direct-path INSERT can be considerably faster than
conventional INSERT.

另解(出处遗忘):
使用这个hint可以将数据使用直接路径插入到表的高水线之后,由于是连续的没有使用的空间,所以插入速度快。就是说直接插入,减少了搜索块的时间.

语法:
    insert /*+append */ into table …
模拟场景:
step0
create table t1(id number(2) primary key);
create table t2(id number(2));
alter table t2 add foreign key (id) references t1(id);
create table t3(id number(2));
insert into t1 select rownum from dual connect by rownum <= 10;

step1
insert /*+append*/ into t2 select * from t1;
select count(*) from t2;
执行正常;

step2
insert /*+append*/ into t3 select * from t1;
select count(*) from t3;
执行出现异常;
ORA-12838:无法在并行模式下修改之后读或修改对象

上述重现了原来看过一位网友给出的测试结果,他给出的结论是:参照完整性约束使append失效,之前在项目也遇到过该问题的我也一直默记这个结论,但是究竟为什么会失效呢?

Next
灵光一现,决定从锁入手,仔细查了一下oracle锁的种类:
表1 Oracle的TM锁类型
锁模式        锁描述        解释        SQL操作
0        none                  
1        NULL        空        Select
2        SS(Row-S)        行级共享锁,其他对象只能查询这些数据行        Select for update、Lock for update、Lock row share
3        SX(Row-X)        行级排它锁,在提交前不允许做DML操作        Insert、Update、Delete、Lock row share
4        S(Share)        共享锁        Create index、Lock share
5        SSX(S/Row-X)        共享行级排它锁        Lock share row exclusive
6        X(Exclusive)        排它锁        Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

接下来,在执行setp1时,
查看v$locked_object
select t1.OBJECT_ID,t1.SESSION_ID,t1.ORACLE_USERNAME,t1.LOCKED_MODE
from v$locked_object t1;
               OBJECT_ID        SESSION_ID        ORACLE_USERNAME        LOCKED_MODE
80798                        306                                        TCS116        3
80796                        306                                        TCS116        2
有点发现了,这里对两个表都加了锁,那么继续刨根:
   select t2.object_name,t2.object_id from user_objects t2 where t2.object_id in (80798,80796)
           OBJECT_NAME        OBJECT_ID
                T1        80796
                        T2        80798
  
在执行setp2时,执行同样操作(合二为一):
select t1.OBJECT_ID, t2.object_name ,t1.SESSION_ID,t1.ORACLE_USERNAME,t1.LOCKED_MODE
from v$locked_object t1, user_objects t2
where t1.OBJECT_ID = t2.object_id
           OBJECT_ID        OBJECT_NAME        SESSION_ID        ORACLE_USERNAME        LOCKED_MODE
                80799                T3                        306                                TCS116        6
明显有个object被锁了,而且还是最高级别的锁,所以你就没办法在去查询或者做其他的dml操作了。

至此个人认为应该是有个了较为合理的解释:在有参照完整性约束时append提示符提供ss行级共享锁;否则提供最高级别的排他锁。

Extend:
append 属于direct insert,归档模式下append+table nologging会大量减少日志,非归档模式append会大量减少日志,append方式插入只会产生很少的undo

 

 

 

 

from:http://www.itpub.net/viewthread.php?tid=1078462

 


参考下列网站
http://space.itpub.net/?uid-185801-action-viewspace-itemid-936

http://www.itpub.net/viewthread.php?tid=979334