table1,table2是存在于不同数据库中的结构基本相同的两张表,假定第一个字段为主键。
现要将table1中不同于table2的新记录(以主键作为表示)插入到table2中。 我用如下的方法做了实现,但这种方法存在的问题是:当数据量相当大时(十万级别),很容易导致内存溢出问题。简略代码如下。 现请教优化的解决问题方案!不胜感激! =========================================== //省略掉的数据库相关操作 
...... //通过调用得到两表的查询结果集 
ResultSet rs1 = selectRS(table1); 
ResultSet rs2 = selectRS(table2); //关闭自动提交 
con.setAutoCommit(false); String baseSql = "insert into table2(ColA,ColB,ColC) values(?,?,?)"; 
PreparedStatement pstmt = con.prepareStatement(baseSql); String str1 = new String(); 
StringBuffer str2 = new StringBuffer(); //将table2的主键字段依次衔接成一个StringBuffer 
while(rs2.next()){ 
str2 = str2.append(rs2.getString(0)).append("-"); 
} int count = 0; 
while(rs1.next()){ 
String str1 = rs1.getString(0); //仅当当前记录是新记录时,列入批处理 
if(str2.indexOf(str1) <0){ 
pstmt.setString(1,str2); 
pstmt.setString(2,rs2.getString(1)); 
pstmt.setString(3,rs2.getString(2)); 
pstmt.addBatch(); 
count++; 
//每2000条记录处理一次 
if (count % 2000 == 0) { 
pstmt.executeBatch(); 



//最后的处理及提交 
pstmt.executeBatch(); 
con.commit(); .............

解决方案 »

  1.   

    每次都全搞一遍效率也太低了,应该在第一个库建立一个触发器,将变化的数据记录到临时表,然后应用程序只处理临时表的数据,处理完清理掉。另外,如果两个数据库互相通的,可以建立dblink,直接写存储过程+job,或者触发器,直接在两个数据库之间搞,不通过程序。
      

  2.   


    确实性能比价差,你的OUtofMemory的exception是在哪里报出了的。batch应该不会报这个错的,如果不是batch这里的错,那么就和oracle没有关系了。你这里你只需要insert新纪录的话可以通过一条sql搞定的呀,可以试试insert into table2 (select * from table1 minus select * from table2);或者用not exists来实现。insert into table2 (select * from table1 where not exists (select 1 from (select table2.pk_filed from table2 where table2.pk_field = table1. pk_field)));如果需要update老数据就需要两条了