Direct-Path Insert 直接路径加载

Oracle直接路径加载解析
本文详细介绍了Oracle数据库中的直接路径加载技术,包括其工作原理、性能优势及应用场景。此外,还探讨了直接路径加载对redo日志的影响、索引维护方式、空间使用情况以及锁定行为。

直接路径加载

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

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

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

下面就是一个insert....values示例(摘自Oracle11gR2Administrator'sGuide)

FORALLiIN1..numrecords

INSERT/*+APPEND_VALUES*/INTOorderdata

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

COMMIT;

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

l必须是Oracle企业版

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

ALTERSESSION{ENABLE|FORCE}PARALLELDML;

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

2.直接路径加载与REDO

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

SQL>select*fromv$versionwhererownum<2;

BANNER

-------------------------------------------------------------------------------OracleDatabase11gEnterpriseEditionRelease11.2.0.1.0-Production

SQL>archiveloglist

DatabaselogmodeArchiveMode

AutomaticarchivalEnabled

ArchivedestinationUSE_DB_RECOVERY_FILE_DEST

Oldestonlinelogsequence7

Nextlogsequencetoarchive9

Currentlogsequence9

SQL>setautottracestat;

SQL>createtabletestasselect*fromdba_objectswhere1=2;

Tablecreated.

SQL>insert/*+append*/intotestselect*fromdba_objects;

72458rowscreated.

Statistics

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

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

8583168redosize

72458rowsprocessed

SQL>commit;

Commitcomplete.

SQL>truncatetabletest;

Tabletruncated.

SQL>insert/*+appendnologging*/intotestselect*fromdba_objects;

72458rowscreated.

Statistics

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

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

8587104redosize

72458rowsprocessed

SQL>commit;

Commitcomplete.

SQL>truncatetabletest;

Tabletruncated.

SQL>altertabletestnologging;

Tablealtered.

SQL>insert/*+append*/intotestselect*fromdba_objects;

72458rowscreated.

Statistics

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

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

56680redosize

72458rowsprocessed

SQL>commit;

Commitcomplete.

SQL>truncatetabletest;

Tabletruncated.

SQL>insert/*+appendnologging*/intotestselect*fromdba_objects;

72458rowscreated.

Statistics

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

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

56380redosize

72458rowsprocessed

SQL>commit;

Commitcomplete.

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

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

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

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

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

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

5.直接路径加载与锁

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

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

<!--EndFragment-->
2025-07-03 17:09:35.078 ERROR 45604 --- [main] o.s.boot.SpringApplication : 818 Application run failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderMapper' defined in file [D:\myworkspace\hr_direct-master\hr-direct-domain\hr-direct-order\hr-direct-order-repository\target\classes\com\alibaba\hrdirect\order\repository\api\OrderMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hrDirectSqlSessionFactory' defined in class path resource [com/alibaba/hrdirect/infrastructure/tddl/ShardingConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\myworkspace\hr_direct-master\hr-direct-domain\hr-direct-order\hr-direct-order-repository\target\classes\mapper\OrderMapper.xml]'; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'file [D:\myworkspace\hr_direct-master\hr-direct-domain\hr-direct-order\hr-direct-order-repository\target\classes\mapper\OrderMapper.xml]'. Cause: java.lang.RuntimeException: Failed to set field value
最新发布
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值