Oracle 数据库引擎提供两种类型的插入(insert )语句来往表中加载数据,即常规插入和直接路径插入。这里介绍直接路径插入,直接路径插入只有在数据库引擎显示要求时才会被使用。直接路径插入的目的就是为了高效地加载大量的数据(对于加载少量数据的情况,它的性能可能还不如常规插入)。它们能够达到这个目标是因为以牺牲部分b.功能为代价来实现的。
直接路径插入只有insert into ….. select …..语句(包括多表插入)、merge语句(针对插入数据部分)和使用oci直接路径接口的应用程序才可以利用直接路径插入。这意味着那些通常使用values子句的插入语句并不支持这个特性。
有两种方式可以使一个insert into ….select …语句使用直接路径插入
A. 在sql 语句中指定append提示:insert /*+ append */ into …select …..
B. 并行地执行sql语句。注意在这里,插入和查询都可以独立地被并行处理。要利用直接路径插入,至少insert部分必须被并行处理。
C. 直接路径插入使用直接写操作,在要修改的段的高水位以上直接加载数据。这个事实会产生以下的重要结果:
1. 由于直接写的缘故,高速缓存被避开了。
2. 不允许再被修改的表上同步地执行delete、insert、merge、update语句,以及索引的创建(重建)操作。自然得通过获得表上的锁来保证这一点。
3. 在高水位以下的包含空闲空间的块也不会被利用,这意味着,即使高水位以下的空间在以后被以清除数据为目的的删除操作(delete)后,还是不能被利用,典型的以空间换效率。
直接路径插入之所以可以获得更好的性能,其中一个原因是,只为这个段生成了最少量的回滚。如果表上有索引,索引段的回滚仍然是正常地生成的。如果要避免生成索引相关的回滚,可以在加载数据之前将索引改为不可用,并在加载结束后来重建这些索引。因为重建索引可能比让数据库引擎在加载完成后维护索引来的更快。
要进一步提高性能,还可以使用最小日志(minimal logging)模式。最小日志模式的目的是使重做(redo)生成最小化。这是个可选项,但是,他对于显著降低相应时间不可或缺。可以在表级别或分区级别设置参数nologging来指定使用最小日志模式。
直接路径插入并不支持所有常规插入操作支持的那些对象。他的功能是受限制的。在数据库引擎无法进行直接路径插入的情况下,这个操作就会自动转换成一个常规插入操作。比如在遇到下列的情况下就会发生:
1. 被修改的表上存在一个insert触发器(注意delete和update触发器对直接路径插入没有影响)。
2. 被修改的表上存在一个激活的外键(其他表的外键指向被修改的表没有问题)。
3. 被修改的表是索引组织表。
4. 被修改的表是属于某个聚簇。
5. 被修改的表中含有对象类型的字段。