5

在过去的几天里,我一直在使用 Oracle 的 SQL*Loader 尝试将数据批量加载到 Oracle 中。在尝试了不同的选项组合后,我惊讶地发现传统路径加载比直接路径加载运行得快得多。

关于这个问题的一些事实:

  • 要加载的记录数为 60K。
  • 加载前目标表中的记录数为 7 亿。
  • Oracle 版本是 11g r2。
  • 数据文件包含日期、字符(ascii,无需转换)、整数、浮点数。没有斑点/斑点。
  • 表按哈希分区。散列函数与 PK 相同。
  • 表的并行设置为 4,而服务器有 16 个 CPU。
  • 索引是本地分区的。索引的平行度(来自 ALL_INDEXES)为 1。
  • 目标表上只有 1 个 PK 和 1 个索引。使用索引构建的 PK 约束。
  • 检查索引分区显示分区之间的记录分布非常均匀。
  • 数据文件是分隔的。
  • 使用了 APPEND 选项。
  • 通过 SQL 选择和删除加载的数据非常快,几乎是即时响应。

使用传统路径,加载在大约 6 秒内完成。

使用直接路径加载,加载大约需要 20 分钟。最糟糕的运行需要 1.5 小时才能完成,但服务器根本不忙。

如果启用了 skip_index_maintenance,则直接路径加载将在 2-3 秒内完成。

我尝试了很多选项,但没有一个能带来明显的改进……不可恢复、已排序索引、多线程(我在多 CPU 服务器上运行 SQL*Loader)。他们都没有改善这种情况。

这是我在 SQL*Loader 以直接模式运行期间一直看到的等待事件:

  • 事件:db 文件顺序读取
  • P1/2/3:文件#、块#、块(从 dba_extents 检查它是一个索引块)
  • 等待类:用户 I/O

有谁知道直接路径加载出了什么问题?或者有什么我可以进一步检查以真正挖掘问题的根本原因吗?提前致谢。

4

1 回答 1

3

I guess you are falling fowl of this

"When loading a relatively small number of rows into a large indexed table

During a direct path load, the existing index is copied when it is merged with the new index keys. If the existing index is very large and the number of new keys is very small, then the index copy time can offset the time saved by a direct path load."

from When to Use a Conventional Path Load in: http://download.oracle.com/docs/cd/B14117_01/server.101/b10825/ldr_modes.htm

于 2011-08-17T10:30:15.230 回答