2010-04-26 102 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