zoukankan      html  css  js  c++  java
  • DirectPath Insert 直接路径加载

     

    直接路径加载

     

    直接路径加载表示绕过buffer cache,直接将数据写入表中。直接路径加载不会将数据写入HWM以下的数据块,而是在HWM之后写入数据,由于绕过了buffer cache,所以直接路径加载的时候性能好于常规路径加载。

    直接路径加载可以并行运行,也可以串行运行,既可以对分区表做直接路径加载,也可以对非分区表做直接路径加载。指定 APPEND hint就表示启用了直接路径加载特征。在11G之前,直接路径加载只支持insert ...select,从11G 开始,Oracle支持insert .... values()启用直接路径加载特征,我们只需要在 insert之后 跟上 /*+ append_values */

    就可以启用直接路径加载。典型应用就是PL/SQL程序中使用了FORALL loop。

    下面就是一个 insert .... values 示例(摘自Oracle11gR2 Administrator's Guide

    FORALL i IN 1..numrecords

                            INSERT /*+ APPEND_VALUES */ INTO orderdata 

            VALUES(ordernum(i), custid(i), orderdate(i),            shipmode(i), paymentid(i));

                    COMMIT;

     

    1.并行直接路径加载满足的条件(缺一不可)

     

    必须是Oracle企业版

    必须在session级别启用并行DML特征,使用下面SQL开启session 并行DML

    ALTER SESSION { ENABLE | FORCE } PARALLEL DML;

    表的DEGREE属性必须大于1或者指定PARALLEL hint在insert关键字之后

     

    2.直接路径加载与REDO

     

    为了一目了然以及更具说服力,我们来做个实验,实验环境Oracle11gR2,归档模式

     

    SQL> select * from v$version where rownum<2;

     

    BANNER

    -------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

     

    SQL> archive log list

    Database log mode              Archive Mode

    Automatic archival             Enabled

    Archive destination            USE_DB_RECOVERY_FILE_DEST

    Oldest online log sequence     7

    Next log sequence to archive   9

    Current log sequence           9

     

    SQL> set autot trace stat;

     

    SQL> create table test as select * from dba_objects where 1=2;

     

    Table created.

     

    SQL> insert /*+ append */into test select * from dba_objects;

     

    72458 rows created.

     

    Statistics

    ----------------------------------------------------------

    ...........缩短篇幅省略之...................

        8583168  redo size

          72458  rows processed

     

    SQL> commit;

     

    Commit complete.

     

    SQL> truncate table test;

     

    Table truncated.

     

    SQL> insert /*+ append nologging */ into test select * from dba_objects;

     

    72458 rows created.

     

    Statistics

    ----------------------------------------------------------

    ...........缩短篇幅省略之...................

        8587104  redo size

          72458  rows processed

     

    SQL> commit;

     

    Commit complete.

     

    SQL> truncate table test;

     

    Table truncated.

     

    SQL> alter table test nologging;

     

    Table altered.

     

    SQL> insert /*+ append */into test select * from dba_objects;

     

    72458 rows created.

     

    Statistics

    ----------------------------------------------------------

    ...........缩短篇幅省略之...................

          56680  redo size   

          72458  rows processed

     

    SQL> commit;

     

    Commit complete.

     

    SQL> truncate table test;

     

    Table truncated.

     

    SQL> insert /*+ append nologging */ into test select * from dba_objects;

     

    72458 rows created.

     

    Statistics

    ----------------------------------------------------------

    ...........缩短篇幅省略之...................

          56380  redo size

          72458  rows processed

     

    SQL> commit;

     

    Commit complete.

     

    实验表明,直接路径加载的时候 加hint nologging是无用的(事实上,根本就没有nologging hint,它只是一个选项,我们可以在create table .... nologging 或者 alter table ...nologging 或者 alter index rebuild nologging 的时候指定),要想减少redo的生成,必须在创建表的时候指定nologging选项或者alter table table_name nologging。注意如果数据库设置为force logging模式,那么将表设置为 nologging会被忽略。

    为什么alter table table_name nologging 之后还是会生成少量的 redo呢?这是因为当一个新的extent产生的时候,Oracle必须记录redo信息,另外当数据字典信息发生变更的时候,Oracle也必须记录redo信息,由于这2部分信息是无法避免的,所以还是会产生少量的redo。

     

    3.直接路径加载时索引的维护

     

    当进行直接路径加载时,如果表/上面有索引,并且索引状态是available,索引的维护工作是在直接路径加载完毕之后进行的。如果在insert的时候启用了并行,那么索引也是并行维护的。如果insert的时候是串行的,那么索引的维护是串行的。所以有时候我们发现直接路径加载花费了很长时间,其实这个时间很可能就是花费在了索引的维护上面。我们最好是在加载数据之前先把索引设置为unusable,当数据加载完毕之后,再以parallel nollgging 的方式rebuild 索引。

     

    4.直接路径加载与空间使用

     

    直接路径加载比常规路径加载要花费更多的空间。由于直接路径加载不会重用已经使用过的数据块,所以直接路径加载相比常规路径加载会使用更多的空间。并行直接路径加载一个非分区表,会使用更多的空间,因为每一个并行子进程都会分配一个临时段来存储数据。

     

    5.直接路径加载与锁

     

         直接路径加载的时候,表会被设置为exclusive 模式,在这个时候用户不能对表进行DML操作,并且用户不能在这个时候建立/重建索引,甚至不能查询。所以我们在使用直接路径加载的时候,要考虑并发。

     

    直接路径加载主要就是这些,更多信息请参考官方文档http://download.oracle.com/docs/cd/E11882_01/server.112/e17120/tables004.htm#CJAEJGJF

     

  • 相关阅读:
    5步教你完成小熊派开发板贴片
    了解JS压缩图片,这一篇就够了
    【华为云推官招募】加入云推官,月入8万的兼职不是梦
    JavaScript中的正则表达式详解
    一瓶可乐的自动售货机指令“旅程”
    年近而立,Java何去何从?
    数据平台、大数据平台、数据中台……你确定能分得清吗?
    微软看上的Rust 语言,安全性真的很可靠吗
    云图说丨手把手教你为容器应用配置弹性伸缩策略
    Spark优化之小文件是否需要合并?
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330581.html
Copyright © 2011-2022 走看看