2013-08-24 39 views
5

Làm cách nào để chèn hơn một triệu hàng trong Oracle theo cách tối ưu cho việc mua sắm sau đây? Nó bị treo nếu tôi tăng vòng lặp FOR lên hàng triệu hàng.Cách nhanh nhất để chèn hàng triệu hàng trong Oracle

create or replace procedure inst_prc1 as 
    xssn number; 
    xcount number; 
    l_start Number; 
    l_end Number; 
    cursor c1 is select max(ssn)S1 from dtr_debtors1; 

Begin 
    l_start := DBMS_UTILITY.GET_TIME; 
    FOR I IN 1..10000 LOOP 
    For C1_REC IN C1 Loop 
     insert into dtr_debtors1(SSN) values (C1_REC.S1+1); 
    End loop; 
    END LOOP; 
    commit; 
    l_end := DBMS_UTILITY.GET_TIME; 
    DBMS_OUTPUT.PUT_LINE('The Procedure Start Time is '||l_start); 
    DBMS_OUTPUT.PUT_LINE('The Procedure End Time is '||l_end); 
End inst_prc1; 
+0

Tôi sẽ không khuyên bạn sử dụng con trỏ cho việc này. Khi con trỏ sẽ giảm hiệu suất của bạn. –

+0

Kiểm tra [link] này (http://www.orafaq.com/wiki/Oracle_Row_Generator_Techniques) – haki

Trả lời

5

Cách tiếp cận của bạn sẽ dẫn đến các vấn đề về bộ nhớ. Cách nhanh nhất sẽ là [Truy vấn này được chỉnh sửa sau nhận xét của David để xử lý kịch bản không có]:

insert into dtr_debtors1(SSN) 
select a.S1+level 
    from dual,(select nvl(max(ssn),0) S1 from dtr_debtors1) a 
connect by level <= 10000 

Phương pháp chọn nhanh nhất là mọi thứ nằm trong RAM. Truy vấn này có thể trở nên chậm nếu nó trượt vào khu vực tạm thời toàn cầu nhưng sau đó cần điều chỉnh DB. Tôi không nghĩ rằng có thể có bất cứ điều gì nhanh hơn này.

ít biết thêm chi tiết về việc sử dụng bộ nhớ bằng cách truy vấn:

Mỗi truy vấn sẽ có PGA [Chương trình khu vực toàn cầu] riêng của mình mà về cơ bản RAM có sẵn cho mỗi truy vấn. Nếu khu vực này không đủ để trả lại kết quả truy vấn thì công cụ SQL bắt đầu sử dụng vùng bảng tạm thời Golabl giống như đĩa cứng và truy vấn bắt đầu trở nên chậm. Nếu dữ liệu cần thiết bởi truy vấn quá lớn đến nỗi ngay cả vùng tạm thời cũng không đủ thì bạn sẽ bị lỗi vùng bảng.

Vì vậy, luôn thiết kế truy vấn để nó vẫn nằm trong PGA khác là cờ Đỏ.

+1

Truy vấn này sẽ không sử dụng vùng bảng tạm thời, nó sẽ thất bại với 'ORA-30009: Không đủ bộ nhớ cho hoạt động CONNECT BY' trước. Đó là loại lẻ vì bạn có thể giải quyết lỗi bằng cách 'thay đổi tập hợp session workarea_size_policy = manual;' và 'thay đổi session set sort_area_size = ;'. Rõ ràng không phải tất cả "loại" đều có thể sử dụng vùng bảng tạm thời. –

+0

Nếu dtr_debtors1 trống thì bạn sẽ chèn null vào bảng. Sử dụng Coalesce (max (ssn), 0). –

2

Chèn một hàng tại một thời điểm với một câu lệnh insert trong vòng lặp chậm. Cách nhanh nhất là sử dụng insert-select như sau, tạo ra hàng triệu hàng và chèn hàng loạt.

insert into dtr_debtors1(SSN) 
select level from dual connect by level <= 1000000; 
+0

Đây không phải là giải pháp đúng. Xem câu trả lời của tôi – Lokesh

+0

Cảm ơn lokiIts đang hoạt động – user1016594

0

Cố gắng thả tất cả các chỉ số tạo ra trên bảng của bạn và sau đó cố gắng chèn bằng cách sử dụng truy vấn select. Bạn có thể thử liên kết này sẽ giúp bạn trong inserting millions of rows nhanh chóng vào cơ sở dữ liệu của bạn.

+0

-1 cho liên kết đó. Nội dung đã lỗi thời, không liên quan và có vấn đề. –

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