8.5 调整数据操作
一些数据操作任务-- 通常是涉及大量数据的操作,可能需要DBA的参与。在加载和删除大量数据时,可以有一些选择,下面各小节将描述这些选择。
8.5.1 大量插入:使用SQL*Loader Direct Path选项
用于Conventional Path模式中时,SQL*Loader从文件中读取记录,生成insert命令,并且将它们传递到Oracle内核。然后,Oracle在表中的空闲块中为这些记录查找存放空间,并且更新任何相关的索引。
在Direct Path模式中,SQL*Loader创建格式化的数据块,并且直接写入到数据文件。这需要偶尔检查数据库以获得数据块的新位置,但不需要其他使用数据库内核的I/O。结果是数据加载过程远快于Conventional Path模式。
如果表上建立了索引,则索引将在加载期间处于DIRECT PATH状态。加载完成后,排序新的键(索引列值),并且将其与索引中已有的键合并在一起。为了维护临时的一组键,加载过程将创建一个临时的索引段,该段 至少与表上最大的索引一样大。通过预先排序数据并在SQL*Loader控制文件中使用SORTED INDEXES子句,可以最小化这种情况的空间需求。
为了最小化在加载期间必需的动态空间分配数量,正在加载进来的数据段应该是已经创建的数据段,并且已经分配了所需要的全部空间。也应该预先排序表中 最大索引的列上的数据。相比于在加载之前删除索引,然后在加载完成后重新创建这些索引,在Direct Path加载期间排序数据并保留表上的索引通常会产生更好的性能。
为了利用Direct Path选项,不可以群集表,也不可以有针对它的其他活动事务。在加载期间,只实施NOT NULL、UNIQUE和PRIMARY KEY约束;在加载完成后,可以自动重新启用CHECK和FOREIGN KEY约束。为了强制进行这种重新启用过程,在SQL*Loader控制文件中使用如下子句:
REENABLE DISABLED_CONSTRAINTS这种重新启用过程的唯一例外是表插入触发器,在重新启用时,不会为表中的每个新行执行表插入触发器。无论这种类型的触发器执行了什么命令,单独的过程必须手动执行这些命令。
在将数据加载到Oracle表中时,SQL*Loader Direct Path加载选项比SQL*Loader Conventional Path加载器提供了更多的性能改进,其方法是绕开SQL处理、缓冲区缓存管理以及不必要的数据块读取。SQL*Loader的Parallel Data Loading选项允许使用多个进程将数据加载到相同的表中,利用系统上多余的资源,从而减少加载过程消耗的总时间。假设有足够的CPU和I/O资源,这 样做就可以极大地减少总的加载时间。
为了使用Parallel Data Loading,使用parallel关键字启动多个SQL*Loader会话(否则,SQL*Loader会在表上放置一个独占的锁)。每个会话都是一 个独立的会话,需要有自己的控制文件。下面的程序清单显示了3个单独的Direct Path加载,它们都在命令行中使用了PARALLEL=TRUE参数:
sqlload USERID=ME/PASS CONTROL=PART1.CTL DIRECT=TRUE PARALLEL=TRUE每个会话默认情况下创建自己的日志文件、错误文件和丢弃文件(part1.log、part2.log、part3.log、part1.bad、 part2.bad等)。因为具有多个将数据加载到相同表中的会话,所以对于Parallel Data Loading,只允许APPEND选项。而对于Parallel Data Loading,不允许SQL*Loader REPLACE、TRUNCATE和INSERT选项。如果在启动加载前需要删除表中的数据,则必须手动删除数据(通过delete或truncate命 令)。如果正在使用Parallel Data Loading,则不可以使用SQL*Loader自动删除记录。
注意:
如果使用Parallel Data Loading,SQL*Loader会话不会维护索引。在启动加载进程之前,必须删除表上的所有索引,并且禁用它的所有PRIMARY KEY和UNIQUE约束。在加载完成后,可以重新创建表的索引。
在串行的Direct Path Loading(PARALLEL=FALSE)中,SQL*Loader将数据加载到表中的盘区中。如果加载过程在加载完成之前失败,一些数据可能会在 过程失败之前提交给表。在Parallel Data Loading中,每个加载过程为加载数据创建临时段。临时段在以后与表合并在一起。如果Parallel Data Loading过程在加载完成之前失败,临时段就不会与表合并。如果临时段没有与加载的表合并,该加载过程中的任何数据都不会提交到表中。
可以使用SQL*Loader FILE参数将每个数据加载会话定向到不同的数据文件。通过将每个数据加载会话定向到它自己的数据文件,可以平衡加载过程的I/O负载。数据加载是I/O 操作非常密集的一个过程,必须分布到多个磁盘上实施并行加载。与串行加载相比,并行加载的性能得到了很大的改善。
Parallel Data Load后,每个会话可能尝试重新启用表的约束。只要至少有一个加载会话仍然在进行中,则尝试重新启用约束就会失败。最后一个完成的加载会话应该尝试重新 启用约束,并且应该会成功。应该在加载完成后检查约束的状态。如果加载的表具有PRIMARY KEY和UNIQUE约束,可以在启用约束前并行创建相关的索引。