我正在使用oracle中的MERGE语句对数百万条记录进行批量插入/更新。好吧,其他选项可能是使用FORALL使用BULKCOLLECT然后提交但是这个操作将再次降低性能,因为我需要保持循环。 完成整个合并操作后提交将是性能损失,我想知道如何将提交频率放在merge语句中,每次说10000行插入/更新就像批量提交一样。
答案 0 :(得分:3)
MERGE语句是一个单一语句,因此根据定义,它不能跨越事务。 (ACID中的A代表原子性。)
如果源表和目标表的合并条件(ON子句)上没有索引,那么将单个MERGE语句转换为N个合并语句将会显着减慢运行速度,就像您执行单个表时一样扫描源和/或目标,你将会做N个。如果您认为一个全表扫描速度很慢,请尝试每百万行执行100次!
老实说,将单个MERGE分成更多语句会变得更慢,因为正在进行更多工作 - 您运行的语句更多,因此解析开销更多,并且您执行更多提交,所以会有更多的序列化,因为你的程序在执行提交时会等待。将单个语句划分为多个的唯一好理由是,如果您有可恢复性问题(哦不!工作失败三小时,我们只有四个小时的窗口!)或者如果事务管理开销(UNDO和ORA-01555的)成为一个问题。
如果您有此进程的CPU可用性,您可能希望考虑对MERGE语句使用PARALLEL提示,以查看它是否运行得更快。类似地,如果您的MERGE语句仅影响目标表中的一小部分行,那么正在合并的列上的索引可能会提高性能。
答案 1 :(得分:-1)
您不能对单个合并语句进行批量提交。