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