从Java批量插入Oracle

我需要在Oracle中快速插入许多小行。 (5个领域)。

使用MySQL,我将插入分成100个组,然后对每组100个插入使用一个insert语句。

但是对于Oracle,用户反馈是质量插入(1000-30000之间)太慢。

有没有类似的技巧可以用来加速从Java到Oracle的程序化插入?

您可以使用Spring的DAO模块批量插入多行。

在一次更新中将Order对象集合插入数据库的示例:

public class OrderRepositoryImpl extends SimpleJdbcDaoSupport implements OrderRepository { private final String saveSql = "INSERT INTO orders(userid, username, coffee, coffeename, amount) " + "VALUES(?, ?, ?, ?, ?)"; public void saveOrders(final Collection orders) { List ordersArgumentList = new ArrayList(orders .size()); Object[] orderArguments; for (Order order : orders) { orderArguments = new Object[] { order.getUserId(), order.getUserName(), order.getCoffe(), order.getCoffeeName(), order.getAmount() }; ordersArgumentList.add(orderArguments); } getSimpleJdbcTemplate().batchUpdate(saveSql, ordersArgumentList); } } 

您不会保留将这些记录传递到数据库的方式。 最好的方法是使用数组,因为这允许使用Oracle的大量漂亮的FORALL批量操作。

此示例包有两个过程。 一个填充T23记录集合(一个包含五个数字列的表)和一个使用数组批量将记录插入该表的表。

 SQL> create or replace package p23 as 2 type t23_nt is table of t23%rowtype; 3 function pop_array ( p_no in number ) 4 return t23_nt; 5 procedure ins_table ( p_array in t23_nt ); 6 end p23; 7 / Package created. SQL> create or replace package body p23 as 2 3 function pop_array ( p_no in number ) 4 return t23_nt 5 is 6 return_value t23_nt; 7 begin 8 select level,level,level,level,level 9 bulk collect into return_value 10 from dual 11 connect by level <= p_no; 12 return return_value; 13 end pop_array; 14 15 procedure ins_table 16 ( p_array in t23_nt ) 17 is 18 s_time pls_integer; 19 begin 20 21 s_time := dbms_utility.get_time; 22 23 forall r in p_array.first()..p_array.last() 24 insert into t23 25 values p_array(r); 26 27 dbms_output.put_line('loaded ' 28 ||to_char(p_array.count())||' recs in ' 29 ||to_char(dbms_utility.get_time - s_time) 30 ||' csecs'); 31 end ins_table; 32 end p23; 33 / Package body created. SQL> 

以下是一些示例运行的输出:

 SQL> declare 2 l_array p23.t23_nt; 3 begin 4 l_array := p23.pop_array(500); 5 p23.ins_table(l_array); 6 l_array := p23.pop_array(1000); 7 p23.ins_table(l_array); 8 l_array := p23.pop_array(2500); 9 p23.ins_table(l_array); 10 l_array := p23.pop_array(5000); 11 p23.ins_table(l_array); 12 l_array := p23.pop_array(10000); 13 p23.ins_table(l_array); 14 l_array := p23.pop_array(100000); 15 p23.ins_table(l_array); 16 end; 17 / loaded 500 recs in 0 csecs loaded 1000 recs in 0 csecs loaded 2500 recs in 0 csecs loaded 5000 recs in 1 csecs loaded 10000 recs in 1 csecs loaded 100000 recs in 15 csecs PL/SQL procedure successfully completed. SQL> SQL> select count(*) from t23 2 / COUNT(*) ---------- 119000 SQL> 

我认为在0.15秒内插入100,000条记录应该让所有用户满意。 那么,问题是,你如何处理插入?

现在MySQL是Oracle,所以也许一个更简单的解决方案可能是继续使用MySQL ……

如果没有,那么您应确保在启动插入组之前启动事务,一旦组完成,然后提交事务并为下一组插入启动新事务。

还要检查可能会减慢插入时间的不必要的索引定义。

更新…
批量插入是指ETL (Extract Transform Load)的最后一步,所以您是否考虑使用基于java的ETL工具,如pentaho kettle或talend-studio 。

Pentaho 在这里描述了他们的Oracle Bulk加载设施。

快速谷歌还显示了一些初步证据,表明Talend也对Oracle批量加载有一些支持。