zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    eclipse中解决update maven之后jre被改成1.5的问题
    Navicat for MySQL密鈅
    静态创建和动态创建对象的区别
    vector相关操作总结
    C++的编码技巧相关总结
    关于VS中未经处理的异常的梳理
    头文件用于声明而不是定义
    SQL单表查询练习部分总结
    delete对象时会自动调用类的析构函数
    SQL中的sum在何时会返回为null
  • 原文地址:https://www.cnblogs.com/wangrui1587165/p/9834963.html
Copyright © 2011-2022 走看看