Oracle Hint 之 Append

1 描述

所谓直接路径操作,就是绕过buffer cache,直接将数据插入到表所在的数据文件中;

假如有表A,要将A中的数据插入到表B,在普通的间接插入下,先将A中的数据块传进buffer cache,再将B中的块也传入到buffer cache,在buffer cache的A块中读出行,插入B的块中。B块就变成了脏块,再等DBwn将他们写入数据文件,

2 总结

① 直接路径操作在高水位线以外分配空间,绕过了数据缓冲区,直接将数据插入表所在的数据文件中;

② 直接路径操作不产生redo和undo log,依赖高水点实现回滚。

③ 直接路径插入的时候Oracle会维护索引,为了避免索引的性能影响,可以先删除索引,等插入完成后重新建立。

④ 直接路径插入回答导致对被插入的表加表级锁,在提交之前,别会话不能再对此表进行insert、delete、update等操作。

3 直接路径操作与间接路径操作的不同

直接路径操作在高水位线以外分配空间,绕过了数据缓冲区,直接将数据插入表所在的数据文件中;

① 准备示例数据表

create table student(

stu_id varchar2(4),

stu_name varchar2(100), --姓名

sex varchar2(1),  --性别 1 男  2 女  0 未知

credit integer default 0

);

create table student_temp as select * from student where 1=2;

② 往student表插入数据并提交

insert into student (stu_id, stu_name, sex, credit) values ('0001', '大王', '2', '83');

insert into student (stu_id, stu_name, sex, credit) values ('0002', '刘一', '1', '85');

commit;

查看student表中数据占用的数据块,现在student表中有两行数据,占用数据库70460。

select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from student;

 

查看Buffer cache中student表所占用的缓存。当前包含数据的块70460。

select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name='STUDENT');

 

由于对AA表进行了全表扫描,因此,AA表中高水点下的所有块都被读进了Buffer cache。

③ 使用直接路径插入,并提交

insert /*+ append*/ into student_temp select * from student;

commit;

查看student_temp表中数据占用的数据块,现在student_temp 表中有两行数据,占用数据库70476。

select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from student_temp;

 

Buffer cache中student_temp表所占用的缓存,不包含数据块70746。

select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name='STUDENT_TEMP');

 

几秒钟后在查看缓存中数据,才包含70746(这个是为什么?)

select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name='STUDENT_TEMP');

 

④ 正常插入

insert  into student_temp select * from student;

commit;

查看student_temp表中数据占用的数据块,现在student_temp 表中有四行数据,新数据占用数据库70478。

select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from student_temp;

 

Buffer cache中student_temp表所占用的缓存,不包含数据块70748。

select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name='STUDENT_TEMP');

 

1.4 直接路径插入与回滚

直接路径操作不产生redo和undo log,依赖高水点实现回滚。

1.5 直接路径操作索引

1.6 直接路径操作的锁

直接路径插入回答导致对被插入的表加表级锁,在提交之前,任何会话(包括当前会话)不能再对此表进行insert、delete、update等操作。其他会话可以进行select操作。

① 在同一个会话执行insert,不提交,然后执行select操作

insert /*+ append*/ into student (stu_id, stu_name, sex, credit) values ('0003', '陈二', '2', '86');

select * from student_temp;

 

同一个会话中,未提交之前,其他DML操作也会报此错误

② 换一个会话可以正常执行select操作。Insert等其他DML操作会进入等待状态

直接操作路径:https://blog.csdn.net/rudygao/article/details/40296679

posted @ 2018-09-07 18:57  wangrui1587165  阅读(1510)  评论(0编辑  收藏  举报