2009-05-19 68 views
11

discussion約多行插入到Oracle兩種方法進行了論證:插入多行到Oracle

第一:

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 

二:

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; 

誰能爭論偏好使用一個在另一個?

P.S.我沒有自己做任何研究(甚至解釋計劃),所以任何信息或意見將不勝感激。

謝謝。

回答

2

利用UNION ALL的聲明在理論上有一個小的性能劣勢,因爲它必須在插入發生之前聯合所有語句的結果。 INSERT ALL沒有這個缺點,因爲最終結果可能已經逐行處理。

但實際上,Oracle內部的優化器應該使差異微乎其微,並且您選擇哪種方式取決於您的偏好。

以我自己的觀點,INSERT ALL是兩個更好的人類可讀的,而UNION ALL變種是這樣一個插入時自動生成的空間較少的變種。

+0

同意結論,但是: Nitpick:這些INSERT語句不返回任何值,因此在「插入可能發生之前」或「逐行」之前發生任何事情都沒有意義。無論如何,他正在使用UNION ALL,所以如果這就是你所想的那樣,就沒有任何問題。 – 2009-05-20 02:38:31

+1

一個快速的「解釋計劃」顯示,具有4行int SCOTT.EMP的INSERT ALL的成本爲2(雙選中唯一CPU成本爲1的多表插入),而UNION ALL變體具有成本8(每個SELECT導致另一個2)。它沒有排序,但結果和單個(至少FAST DUAL)的組合會選擇哪個導致成本。 – Kosi2801 2009-05-20 06:58:16

3

我會懷疑解決方案1是一種有效的破解方法,可能比Insert ALL的設計方案效率低。

插入一切都是真的爲您設計許多行插入到超過1臺作爲一個選擇,如結果:

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

如果要加載數千行的,他們是不是在數據庫已經是,我不認爲這是最好的辦法 - 如果你的數據在一個文件中,你想看看外部表或SQL加載程序來爲你有效地插入行。

7

從性能的角度來看,這些查詢是相同的。

UNION ALL不會損害性能,因爲Oracle只在需要時纔會估計UNION'ed查詢,它不會先緩存結果。

SELECT語法更靈活,從這種意義上說,如果您想更改某些內容,您可以更輕鬆地處理SELECT查詢。

例如,這個查詢:

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 

可以改寫爲

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 

通過與適當數量的替代2,你可以得到你想要的任何數量的行。

INSERT ALL的情況下,您將不得不復制目標表格描述,如果您需要,例如40行,則描述的可讀性會降低。

+1

請注意,使用`SOME_SEQUENCE.NEXTVAL`作爲值,會導致Oracle錯誤** ORA-02287:此處不允許序列號**(Oracle 11g)。這裏描述了一個解決方法:http://www.orafaq.com/forum/t/54217/2/ - 嘗試`INSERT INTO ... SELECT SOME_SEQUENCE.NEXTVAL,T * FROM(SELECT ... UNION ALL SELECT。 ..)T` – 2011-11-10 17:31:00

3

INSERT ALL方法在將較大數量的行插入表中時存在問題。

我最近想用單個SQL語句將1130行插入到表中。當我試圖用INSERT ALL的方法來做到這一點,我得到了以下錯誤:

ORA-24335 - cannot support more than 1000 columns

當我用INSERT INTO .. UNION ALL ..做法一切正常。

Btw。我不知道該UNION ALL方法之前,我發現這個討論:)

2

我嘗試了一些測試和更快的解決方案應該是

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 

緩衝<之間300 - > 400行(我試過用odbc,這個值可能取決於它的配置)

-2

你應該考慮數組插入。

  • 易SQL
  • 需要一些客戶端編碼設置陣列參數

這是爲了減少網絡的流量,如果幾百插入需要在一個批次做的方式。

-1

如果插入語句大於1000,則將所有插入語句放在.sql文件中,並在Toad或SQL Developer中打開該語句,然後執行。所有記錄都會被插入。