2010-04-26 34 views
14

Tôi cần chèn nhiều hàng nhỏ nhanh chóng vào Oracle. (5 trường).chèn số lượng lớn từ Java vào Oracle

Với MySQL, tôi chia phần chèn thành các nhóm 100, sau đó sử dụng một câu lệnh chèn cho mỗi nhóm 100 lần chèn.

Nhưng với Oracle, phản hồi của người dùng là chèn khối lượng (bất cứ nơi nào từ 1000-30000) quá chậm.

Có mẹo tương tự nào tôi có thể sử dụng để tăng tốc độ chèn chương trình từ Java vào Oracle không?

+0

kịch bản xây dựng sqlplus, cho Java/etc để gọi chứ không phải làm việc đó tất cả thông qua Java. –

Trả lời

0

Ngày nay MySQL là Oracle vì vậy có lẽ một giải pháp đơn giản có thể để ở trên MySQL ...

Nếu không được thì bạn nên đảm bảo rằng giao dịch được bắt đầu trước khi bạn bắt đầu nhóm bạn của chèn, khi nhóm là đã hoàn thành rồi giao dịch và bắt đầu một giao dịch mới cho nhóm chèn tiếp theo.

Đồng thời kiểm tra các định nghĩa chỉ mục không cần thiết có thể làm chậm thời gian chèn.

Cập nhật ...
chèn hàng loạt đề cập đến bước cuối cùng của ETL (Extract Chuyển Load), vì vậy có bạn xem là sử dụng một java dựa trên công cụ ETL như pentaho kettle hoặc talend-studio.

Pentaho mô tả các cơ sở tải hàng loạt của Oracle here.

Một google nhanh chóng cũng cho thấy một số bằng chứng sơ bộ rằng Talend cũng có một số hỗ trợ cho tải hàng loạt của Oracle.

+4

MySQL rõ ràng không phải là Oracle. Công ty là, nhưng phần mềm thì không. Bên cạnh đó-- đó là sự lựa chọn của khách hàng. Tôi thích MySQL nhưng chúng tôi cần hỗ trợ cả hai. –

+0

Chỉ để xác nhận, tất cả đã nằm trong một giao dịch. –

+1

Nhận xét về việc lưu trú trên MySQL bởi vì nó là Oracle có nghĩa là được đưa ra như một trò đùa ... sắp xếp ... tôi lại đi ... – crowne

2

Bạn không giữ nguyên cách bạn chuyển các bản ghi này vào cơ sở dữ liệu. Cách tốt nhất là sử dụng một mảng, vì điều này cho phép sử dụng nhiều hoạt động hàng loạt FORALL của Oracle.

Gói ví dụ này có hai quy trình. Một tệp sẽ điền một tập hợp các bản ghi T23 (một bảng bao gồm năm cột số) và một bản ghi hàng loạt chèn các bản ghi vào bảng đó bằng cách sử dụng một mảng.

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> 

Đây là kết quả từ một số chạy mẫu:

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> 

Tôi nghĩ chèn 100.000 hồ sơ trong 0,15 giây nên hài lòng tất cả nhưng đòi hỏi khắt khe nhất của người sử dụng. Vì vậy, câu hỏi là, làm thế nào để bạn tiếp cận chèn của bạn?

+1

Cảm ơn! Với jdbc từ java, đó là ràng buộc duy nhất của tôi. –

10

Bạn có thể sử dụng mô-đun DAO của Spring để chèn hàng loạt nhiều hàng.

Một ví dụ đó chèn một tập hợp các đối tượng theo thứ tự vào cơ sở dữ liệu trong một bản cập nhật:

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

điều cần biết. Tôi không sử dụng Spring ở đây, nhưng sẽ ghi nhớ điều này. –

+0

Lợi thế của giải pháp này là nó gửi tất cả dữ liệu ở cuối như là một gói lớn. Nếu bạn đang thực hiện cập nhật cho mỗi hàng, thì bạn cũng gửi qua mạng. JPA cũng cung cấp các giải pháp lô tương tự như giải pháp Spring này. – Espen

Các vấn đề liên quan