Welcome 微信登录

首页 / 数据库 / MySQL / Oracle直接路径加载--append的深度解析

 ㈠ 直接路径加载和buffer cache直接路径插入的数据不经过buffer cache,从PGA直接把数据格式化成Oracle块然后由普通的Oracle Server Process进程把数据块写入数据文件因为不经过buffer cache,所以不需要DBWn介入假如有表a,现要将a中的数据插入表b,在普通的插入下,需先将a的数据块I/O到buffer cache在buffer cache中从a的块中读出行,插进b的块中此时,b的块就都变成了脏块,再等待DBWn把他们flush到数据文件因此,普通插入后,a表和b表的块都会在buffer cache中出现而直接路径插入,将a表的数据块I/O到buffer cache,读出行,直接写进b表所在的数据文件插入完成后,除了表头块外,b表的数据块并未在buffer cache中出现过测试:hr@ORCL> create table a (id number,name varchar2(10));Table created.hr@ORCL> create table b (id number,name varchar2(10));Table created.hr@ORCL> insert into a values(1,"aa");1 row created.hr@ORCL> insert into a values(2,"bb");1 row created.hr@ORCL> insert into a values(3,"cc");1 row created.hr@ORCL> insert into a values(4,"dd");1 row created.hr@ORCL> commit;Commit complete.hr@ORCL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from a;DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                  4                                  508
                                  4                                  508
                                  4                                  508
                                  4                                  508
--现在a表有4行,占用块508,而目前b表还木有数据
 
--将buffer cache清空hr@ORCL> alter system flush buffer_cache;System altered.--先用直接路径插入,从a表向b表插入数据hr@ORCL> insert /*+ append */ into b select * from a;4 rows created.hr@ORCL> commit;Commit complete.--使用v$bh查看buffer cache中的块hr@ORCL> select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name="A");    FILE#    BLOCK#
---------- ----------
        4        508    ←←当前包含数据的块
        4        508    ←←当前包含数据的块
        4        511
        4        511
        4        506
        4        509
        4        509
        4        512
        4        512
        4        507
        4        507
        4        510
        4        510
        4        50514 rows selected.--这是因为对a表进行全表扫,a表中低高水位点下所有的块都被读进buffer cache,这其中当然也包括508了hr@ORCL> select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name="B");    FILE#    BLOCK#
---------- ----------
        4      2571
        4      2569
        4      2570hr@ORCL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from b;DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                  4                                2572
                                  4                                2572
                                  4                                2572
                                  4                                2572
--上面两个查询可以看到,b表中的数据占用地2572块,但是,直接路径插入后,2572并没有被调入buffer cache
--buffer cache中只有2569 2570 2571
--其中2571是段头块(select header_file,header_block from dba_segments where segment_name="B")
--2570 2569则是L1 L2这两个位图块
--接下来使用普通插入
hr@ORCL> alter system flush buffer_cache;System altered.hr@ORCL> insert into b select * from a;4 rows created.hr@ORCL> commit;Commit complete.hr@ORCL> select file#,block# from v$bh where objd=(select data_object_id from user_objects where object_name="B");    FILE#    BLOCK#
---------- ----------
        4      2571
        4      2574
        4      2569
        4      2575
        4      2570
        4      2570
        4      2573
        4      2576  ←←本次普通插入的数据所在的块8 rows selected.hr@ORCL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from b;DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                  4                                2572
                                  4                                2572
                                  4                                2572
                                  4                                2572
                                  4                                2576
                                  4                                2576
                                  4                                2576
                                  4                                25768 rows selected.从上面的实验可以证明,普通插入,要先将数据块传进buffer cache这是Oracle通常修改数据的方式,不对数据文件直接进行修改,而是在内存中完成修改,再由日志提供保护对于小量的修改,这是种可取的方法,但对于大数据交易,直接路径将可以提供更好的性能还有就是,直接路径加载是在高水位之上完成的插入动作,因此无论高水位下有多少空闲块都会被忽略,段空间将会随之增大
  • 1
  • 2
  • 3
  • 4
  • 下一页
为Sybase ASA创建外部存储过程(Java示例)针对Oracle用户的Linux高级命令详解之资源管理篇相关资讯      Oracle入门教程  Oracle append  Oracle直接路径加载 
  • 使用SQLT来构建Oracle测试用例  (08/28/2014 06:17:41)
  • Oracle AUTOTRACE 统计信息  (02/18/2013 08:25:40)
  • Oracle Connect By用法  (12/16/2012 13:36:10)
  • Oracle入门教程:把表和索引放在不  (07/13/2013 11:21:40)
  • Linux Oracle服务启动&停止脚本与  (12/16/2012 14:42:37)
  • Oracle sql_not exists与null的测  (12/16/2012 13:11:25)
本文评论 查看全部评论 (0)
表情: 姓名: 字数

版权所有©石家庄振强科技有限公司2024 冀ICP备08103738号-5 网站地图