1

我有一个 Oracle PL/SQL 脚本。它处理大约 51 万个寄存器,并将结果写入 5 个不同的表。

问题是我昨晚让进程运行,显然UNDO日志中有溢出。

特别是,我们对回滚这个脚本不感兴趣,如果它失败了,我们可以再次运行它。

有没有办法优化撤消/重做日志的使用?避免写它们或最小化这些写?

据我了解,除了使用 APPEND 插入(如此所述)之外,设置输出表的 NOLOGGING 属性会有所帮助。

4

5 回答 5

2

您不应该只处理一个批次的 5100 万个寄存器。例如,试着把它分成几千个更小的块。如果您在每个较小的批次之后执行 COMMIT(无论如何您都会这样做,因为您说您不会回滚),重做/撤消日志的使用将仅用于未提交的部分,并且您将避免溢出。

于 2009-12-01T15:16:08.997 回答
1

此外,禁用约束和索引也可以加快插入速度。您可以使用 nologging 重建索引。

于 2009-12-01T19:40:23.987 回答
1

这真的是一个问题,或者减少你正在做的工作量。

直接路径插入上的表 UNDO 总是很小,因为系统只需要记录应该从段中删除某些范围的块。尽管如此,索引仍然需要大量撤消。直接路径插入上的无日志记录可最大限度地减少表 REDO。

于 2009-12-01T16:28:18.540 回答
0

“特别是,我们对回滚这个脚本不感兴趣,如果它失败了,我们可以再次运行它。”

一个问题是,您是否需要并且准备好返回之前的备份以便再次运行脚本?也就是说,如果该过程在 1000 万行之后失败,则只需重新运行脚本会导致插入 6100 万行,或者会跳过/忽略 1000 万行,还是会更新 1000 万行并插入 4100 万行。

此外,如果您执行 NOLOGGING 插入,则可能需要在作业后立即进行新备份。在脚本运行期间将时间点恢复到某个时间时会遇到问题,因此您还需要考虑脚本运行时数据库上发生的其他活动。

根据您编写 PL/SQL 脚本的方式,您可能会发现使用大型 SQL,而不是逐行处理,可以减少撤消(例如,通过最小化对已处理块的重新访问)。

除非您真正了解减少撤消或承诺允许重用撤消的影响,否则我的第一个建议是简单地增加撤消表空间的大小。当然,你确实有一个缺点,如果你已经生成了大量的 undo,那么失败将需要很长时间才能回滚。

于 2009-12-01T21:40:10.470 回答
0

您还可以使用隐藏参数 _disable_logging = true 来减少重做,但要注意生成的导入将无法恢复。

于 2016-11-01T02:15:28.630 回答