现有一张目标表des,另有一张源数据表src。这两个表中的数据量都很大,且都有超过上亿条的数据。
目标:把src表中的数据写入des中,且如果数据在des中存在,则忽略。刚一开始我用了例外表的方法实现,类似如下:while src has data loop
  --每次只写入10000条数据,循环执行
  update src set flag='1' where flag is null and rownum<10000;
  
  insert into des select * from src where flag=1 log errors into err_log_table...  update src set flag='2' where flag='1'
end loops;但是运行一段时间后,我试图充分利用服务器的高性能,所以,希望用多线程并发的方式提高性能。于是简单做了一下修改:alter session enable parallel dml;while src has data loop
  --每次只写入10000条数据,循环执行
  update /*+ parallel(a,8) */ src a set flag='1' where flag is null and rownum<10000;
  
  insert /*+ parallel(a,8) */ into des a select /*+ parallel(b,8) */  * from src b where flag=1 log errors into err_log_table...  update /*+ parallel(a,8) */  src a set flag='2' where flag='1'
end loops;
但是,发现如果这个时候有主键冲突的情况时,系统就直接报“违反唯一约束条件”这样的错误了,而不是像第一种情况时,写入例外表中。不知道各位有没有遇到过这种并发处理时类似的问题。或者说对这样一种大数据量写入,有没有什么更好的建议。

解决方案 »

  1.   

    分区表确实是要考虑,可是现在问题的关键是,如果没有主键冲突的时候,数据写入还是比较快的,用方法2,一次性写入200万条数据,也只需要1分钟左右的时间。但是有冲突的时间,程序就down掉了。改为方法1还是可以继续跑的,只是效率上要差很多。我也想过先把冲突部分的数据找出来,但是这样就涉及到两个大表之间的关联查询,开销也是不小的。所以,现在我最希望有谁能够帮我解决并发写入时如何把异常情况写入例外表中。