2010-04-26 76 views
14

我需要将许多小行快速插入到Oracle中。 (5个领域)。从Java到Oracle的批量插入

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

但是对于Oracle来说,用户的反馈是质量插入(从1000到30000的任何地方)太慢了。

是否有类似的技巧可以用来加速从Java到Oracle的编程插入?

+0

构建的SQLPlus脚本,为Java /等等调用,而不是通过Java做这一切。 – 2010-04-26 21:00:25

回答

0

如今MySQL是甲骨文所以也许一个简单的解决方案可能是留在MySQL的

如果没有,那么你应该确保在交易开始启动您的刀片组之前,一旦组是完成后提交事务并为下一组插入启动一个新的事务。

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

更新...
批量插入指ETL最后一步(提取转换加载),所以你考虑使用基于Java的ETL工具如pentaho kettletalend-studio

Pentaho描述了他们的Oracle Bulk loading设施here

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

+4

MySQL显然不是Oracle。该公司是,但该软件不是。此外 - 这是客户的选择。我更喜欢MySQL,但我们需要支持这两者。 – 2010-04-26 21:49:36

+0

只是为了确认,它已经全部在单个交易中。 – 2010-04-26 21:53:57

+1

有关留在MySQL上的评论,因为它是Oracle,本来是想当个笑话...排序......那里我再去...... – crowne 2010-04-27 20:25:16

2

你不留你如何传递这些记录到数据库。最好的方法是使用一个数组,因为这允许使用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条记录应该请,但所有最苛刻的用户。所以,问题是,你如何处理你的插入?

+1

谢谢!使用java的jdbc,这是我唯一的约束。 – 2010-04-27 04:23:44

10

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

进行的插入顺序对象的集合到数据库中的一个更新的一个例子:

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<Order> orders) { 
     List<Object[]> ordersArgumentList = new ArrayList<Object[]>(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); 
    } 
} 
+0

相关提示我不是在这里使用Spring,但会牢记这一点。 – 2010-04-27 23:09:23

+0

该解决方案的一个优点是它将最后的所有数据作为一个大包发送。如果你正在执行每一行的更新,那么你也可以通过网络发送。 JPA也提供与此Spring解决方案类似的批处理解决方案。 – Espen 2010-04-28 09:52:40