【问题标题】:How can I specify Batch commit in Oracle Merge Statement?如何在 Oracle 合并语句中指定批量提交?
【发布时间】:2010-02-16 12:59:09
【问题描述】:
我正在使用 oracle 中的 MERGE 语句对数百万条记录进行批量插入/更新。好吧,其他选项可能是使用 FORALL 并利用 BULKCOLLECT 然后提交,但是此操作将再次降低性能,因为我需要保持循环。
在完成整个合并操作后提交将影响性能,我想知道如何将提交频率放在合并语句中,以便每说 10000 行插入/更新,例如批量提交。
【问题讨论】:
标签:
batch-file
oracle10g
commit
merge-statement
【解决方案1】:
MERGE 语句是一个单一的语句,因此根据定义,它不能跨越事务。 (ACID 中的 A 代表原子性。)
如果您在源表和目标表的合并条件(ON 子句)上都没有索引,则将单个 MERGE 语句转换为 N 个合并语句会运行得非常慢,就像您执行单个扫描源和/或目标,你将要做其中的 N 个。如果您认为一次全表扫描很慢,请尝试每百万行扫描 100 次!
老实说,将单个 MERGE 拆分为更多语句会变得更慢,因为正在完成更多工作 - 您正在运行更多语句,因此会有更多解析开销,并且您正在执行更多提交,所以会有更多的序列化,因为你的程序在提交执行时等待。将单个语句划分为多个语句的唯一充分理由是,如果您有可恢复性问题(哦不!作业在三个小时内失败,而我们只有四个小时的窗口!)或者事务管理开销(UNDO 和 ORA-01555 的) 成为一个问题。
如果您有可用于此进程的 CPU,您可能希望考虑对您的 MERGE 语句使用 PARALLEL 提示,以查看它是否运行得更快。同样,如果您的 MERGE 语句只影响目标表中的一小部分行,那么合并所针对的列上的索引可能会提高性能。