2009-05-19 55 views
11

Trong discussion về nhiều hàng chèn vào Oracle hai phương pháp đã được chứng minh:Chèn nhiều hàng vào Oracle

Đầu tiên:

insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE) 
      select 8000,0,'Multi 8000',1 from dual 
union all select 8001,0,'Multi 8001',1 from dual 

Thứ hai:

INSERT ALL 
    INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3') 
    INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3') 
    INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3') 
    . 
    . 
    . 
SELECT 1 FROM DUAL; 

bất cứ ai có thể tranh luận sở thích sử dụng cái khác?

P.S. Tôi không tự mình nghiên cứu (ngay cả kế hoạch giải thích), vì vậy bất kỳ thông tin hoặc ý kiến ​​nào cũng sẽ được đánh giá cao.

Cảm ơn.

Trả lời

2

Tuyên bố sử dụng UNION ALL về lý thuyết có một bất lợi hiệu suất nhỏ vì nó phải kết hợp các kết quả của tất cả các câu lệnh trước khi chèn có thể xảy ra. INSERT ALL không có bất lợi này vì kết quả cuối cùng có thể đã được xử lý theo từng dòng.

Nhưng thực tế trình tối ưu hóa bên trong Oracle sẽ làm cho sự khác biệt không đáng kể và tùy thuộc vào sở thích của bạn theo cách bạn chọn.

Theo ý kiến ​​riêng của tôi, INSERT ALL là người có thể đọc được tốt hơn của hai trong khi biến thể UNION ALL là một biến mất ít không gian hơn khi chèn như vậy được tạo tự động.

+0

Đồng ý với kết luận, nhưng: Nitpick: các câu lệnh INSERT này không trả về bất kỳ giá trị nào, vì vậy sẽ không có nghĩa gì khi nói "trước khi chèn có thể xảy ra" hoặc "từng dòng". Dù sao, anh ấy sử dụng UNION ALL nên không có vấn đề gì với các loại, nếu đó là những gì bạn đang nghĩ đến. –

+1

Một "kế hoạch giải thích" nhanh chóng cho thấy rằng INSERT ALL với 4 dòng int SCOTT.EMP có chi phí 2 (1 chèn nhiều bảng với chi phí CPU duy nhất trong lựa chọn kép) trong khi biến thể UNION ALL có chi phí của 8 (với mỗi SELECT gây ra 2). Nó không phân loại nhưng kết hợp các kết quả và các lựa chọn đơn (ít nhất là NHANH CHÓNG) đang gây ra chi phí. – Kosi2801

3

Tôi nghi ngờ giải pháp 1 là một chút hack hoạt động và có lẽ kém hiệu quả hơn so với thay thế được thiết kế của TẤT CẢ TẤT CẢ.

Chèn tất cả được thực sự được thiết kế để bạn có thể chèn nhiều hàng vào hơn 1 bảng như là kết quả của một lựa chọn, ví dụ:

Insert ALL 
into 
    t1 (c1, c2) values (q1, q2) 
    t2 (x1, x2) values (q1, q3) 
select q1, q2, q3 from t3 

Nếu bạn muốn tải hàng ngàn hàng và họ đang không ở trong cơ sở dữ liệu đã là, tôi không nghĩ đây là cách tốt nhất để làm điều đó - Nếu dữ liệu của bạn nằm trong tệp, bạn muốn xem Bảng bên ngoài hoặc Trình tải SQL để chèn hàng hiệu quả cho bạn.

7

Từ quan điểm của hiệu suất, các truy vấn này giống hệt nhau.

UNION ALL sẽ không ảnh hưởng đến hiệu suất, vì Oracle ước tính chỉ truy vấn được chỉnh sửa UNION khi nó cần, nó không lưu trước kết quả. Cú pháp

SELECT linh hoạt hơn theo nghĩa đó bạn có thể dễ dàng điều khiển truy vấn SELECT nếu bạn muốn thay đổi điều gì đó.

Ví dụ, truy vấn này:

insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE) 
      select 8000,0,'Multi 8000',1 from dual 
union all select 8001,0,'Multi 8001',1 from dual 

có thể được viết lại như

INSERT 
INTO pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE) 
SELECT 7999 + level, 0, 'Multi ' || 7999 + level, 1 
FROM dual 
CONNECT BY 
     level <= 2 

Bằng cách thay thế 2 với số lượng thích hợp, bạn có thể nhận được bất kỳ số lượng hàng mà bạn muốn.

Trong trường hợp INSERT ALL, bạn sẽ phải sao chép mô tả bảng đích, ít có thể đọc được nếu bạn cần, ví dụ: 40 hàng.

+1

Lưu ý rằng việc sử dụng 'SOME_SEQUENCE.NEXTVAL' làm giá trị, cho một lỗi Oracle ** ORA-02287: số thứ tự không được phép ở đây ** (Oracle 11g). Một giải pháp được mô tả ở đây: http://www.orafaq.com/forum/t/54217/2/ - thử 'INSERT INTO ... SELECT SOME_SEQUENCE.NEXTVAL, T. * FROM (SELECT ... UNION ALL SELECT. ..) T' –

3

Phương thức INSERT ALL có vấn đề với việc chèn số hàng lớn hơn vào bảng.

Gần đây tôi đã muốn chèn 1130 hàng vào một bảng với câu lệnh SQL đơn. Khi tôi cố gắng làm điều này với INSERT ALL phương pháp tôi đã nhận lỗi sau:

ORA-24335 - cannot support more than 1000 columns

Khi tôi sử dụng cách tiếp cận INSERT INTO .. UNION ALL .. tất cả mọi thứ diễn ra tốt đẹp.

Btw. Tôi không biết về UNION ALL phương pháp trước khi tôi thấy cuộc thảo luận này :)

2

tôi đã cố gắng một số thử nghiệm và các giải pháp nhanh hơn nên

insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE) 
      select 8000,0,'Multi 8000',1 from dual 
union all select 8001,0,'Multi 8001',1 from dual 

đệm giữa 300 < -> 400 hàng (tôi đã cố gắng với odbc, giá trị này có thể phụ thuộc vào cấu hình của nó)

-2

Bạn nên xem xét Mảng-Chèn.

  • Dễ SQL
  • cần một số mã hóa client-side để thiết lập các mảng-Tham số

Đây là cách để giảm thiểu Mạng-Traffic nếu vài trăm chèn cần phải được thực hiện trong một lô .

-1

Nếu bạn có chèn câu lệnh nhiều hơn 1000, sau đó đặt tất cả các câu lệnh chèn vào tệp .sql và mở câu lệnh đó trong Toad hoặc SQL Developer và sau đó thực thi. Tất cả hồ sơ sẽ được chèn vào.

+0

OP muốn biết liệu một trong các cách tiếp cận mà ông đã đề cập có được ưu tiên hơn cái kia hay không, nó không phải là về cách thức/nơi thực thi SQL. – dlatikay

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