日期:2014-05-17  浏览次数:20617 次

向oracle中一次插入100万笔以上数据优化
最近遇到一个做insert动作时时间太长的问题,某个方法一次向一个表中插入了130万笔的数据(无关联表),大概用时70分钟左右。
现在想优化一下,尽最大能力减少所用时间。
以下是方法中的部分代码:
sqlConnForScp = as.getConnection();
 (CN_QTY,CN_ID,CR_PROGRAM,CL_LEVEL,CN_FSE,CR_PAR_PRODUCT,CR_PRODUCT,CR_PERIOD_ID) ");
  sqlConnForScp.setAutoCommit(false);
  String insertSql = "insert into TN_CURVE_DETAIL (CN_QTY,CN_ID,CR_PROGRAM,CL_LEVEL,CN_FSE,CR_PAR_PRODUCT,CR_PRODUCT,CR_PERIOD_ID) Values (?,?,?,?,?,?,?,?)";
  pstmt = sqlConnForScp.prepareStatement(insertSql);

pstmt.setDouble(1, Double.parseDouble(quantity));
……
……
pstmt.addBatch();


我设置的是每1万笔数据执行一次pstmt.executeBatch();并提交。
1万笔用时大概是30-40秒之间,我也试过5000笔,基本是一半时间。

个人觉得代码方面好像没太大提高了。是否还有更好的方法来做插入呢?请高手和有经验的朋友帮忙!

------解决方案--------------------
写在存储过程中,在java代码中直接调用这个存储过程,存储过程中分成两次做提交,每次分成50万提交一次,用游标记住第一提交的索引,然后第二次就从该索引处全部提交完,这样只需要几分钟就搞定,之强有个项目业是遇到这样的情况,就是这样处理的。
------解决方案--------------------
130 万 70 分钟基本上差不多了。

如果表中建有索引的话,就先把索引删掉,使用 Oracle 的专用优化器不让 INSERT 写回滚段日志,这样速度也可能会快很多。
------解决方案--------------------
存储过程吧

一次把数据“扔”给db服务器,
也快
也安全
总比你远程连接发送一条条指令要快...吧?!

没那么多数据实验
几近胡说

good luck
------解决方案--------------------
尽量用存储过程,要是用代码的话,就要考虑事务回滚,有IO和内存异常
------解决方案--------------------
insert /*+append */ into 表 as select 数据 试下
------解决方案--------------------
使用PreparedStatement + 使用批处理 !