2013-08-06 26 views
4

我這是在WAN緩慢運行的應用程序 - 我們認爲原因是多個插入到一個表。我目前正在研究更有效的方法來同時插入多行。的Oracle 11g - 將多行的最有效的方式

我發現這個方法:

INSERT ALL 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (100,20) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (21,2) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (321,10) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (22,13) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (14,121) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (11,112) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (112,23) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (132,2323) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (121,34) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (24333,333) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (1232,3434) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (4554,3434) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (3434,211) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (3434,1233) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (12,22) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (356,233) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (9347,23) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (8904,245) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (342,4545) 
    INTO MULTI_INSERT(VAL_1, VAL_2) VALUES (453,233) 
SELECT 1 FROM DUAL; 

我想知道的是:上面其實不止做20更有效的方法 「INSERT INTO MY_TABLE(1,1);」?還有其他的方法嗎?

+0

是否有表上的所有觸發器? – Harshit

+0

喜Harshit - 不,還有桌子上 – user1578653

+0

沒有觸發想必你的現實生活中的使用情況是超過20行?而不是硬編碼的值? – APC

回答

2

您可以嘗試direct path insert以加快操作速度,但對於100條記錄,傳統路徑插入必須足夠快,並且似乎問題是在從大量源插入日誌時出現表鎖問題。

要指示Oracle使用直接路徑插入,您必須根據插入語句語法指定APPENDAPPEND_VALUES提示。例如。

insert /*+ APPEND */ 
into multi_insert(val_1, val_2) 
select * from (
    select 100, 20 from dual union all 
    select 21,  2 from dual union all 
    select 321, 10 from dual union all 
    select 22,  13 from dual union all 
    select 14, 121 from dual union all 
    select 11, 112 from dual union all 
    select 112, 23 from dual union all 
    select 132, 2323 from dual union all 
    select 121, 34 from dual union all 
    select 24333, 333 from dual union all 
    select 1232, 3434 from dual union all 
    select 4554, 3434 from dual union all 
    select 3434, 211 from dual union all 
    select 3434, 1233 from dual union all 
    select 12,  22 from dual union all 
    select 356, 233 from dual union all 
    select 9347, 23 from dual union all 
    select 8904, 245 from dual union all 
    select 342, 4545 from dual union all 
    select 453, 233 from dual 
) 

如果INSERT語句源自PL/SQL代碼,那麼你可以使用批量插入與FORALL語句來提高性能(SQLFiddle):

declare 
    type TRowList is table of multi_insert%rowtype index by binary_integer; 

    vRowList TRowList; 
    vRow  multi_insert%rowtype; 
begin 


    vRow.val_1 := 100; 
    vRow.val_2 := 20; 
    vRowList(0) := vRow; 

    vRow.val_1 := 21; 
    vRow.val_2 := 2; 
    vRowList(1) := vRow; 

    vRow.val_1 := 321; 
    vRow.val_2 := 10; 
    vRowList(2) := vRow; 

    -- ... 

    forall vIdx in vRowList.first .. vRowList.last 
     insert /*+ APPEND_VALUES */ -- direct path insert 
     into multi_insert values vRowList(vIdx); 

end; 
2

「客戶報告說,它是完美的工作當應用程序 和Oracle在同一個局域網上,但是當他們移居國外的甲骨文 服務器,他們說,程序的執行速度非常慢」

好了,現在我們取得了一些進展。如果你有一個設置,其中你的100條語句是單獨的調用,它們可能會被分開發送。與局域網相比,這將在廣域網上造成痛苦。在這種情況下,將RBAR中的語句轉換爲基於Set的語句會減少傳輸數據包的數量是值得的。

不過,我還是勸你,你滾出去,在更改前得到一些確鑿的事實。您的客戶是否有可以與之通話的網絡管理員?或者至少可以讓他們安裝Wireshark並向您發送一些報告?

+0

我們剛剛設法在VPS上設置了一個遠程Oracle服務器,並將其連接到我們的應用程序。我做了wireshark捕獲,發現它爲每一行發送單獨的數據包。我的一位同事重新編譯了這個應用程序,這次使用了一些名爲「array DML」的Direct Oracle Access(我們用來與Oracle通信的庫)的一些功能。這幾乎不發送任何數據包,幾乎是瞬間的。但是,我想知道這個「數組DML」實際上是什麼,因爲我們有其他(非Delphi)應用程序可能會遇到同樣的問題 - 您能否介紹一下這個問題? – user1578653

+0

可能DOA使用OCI中的[APPEND_VALUES提示](http://docs.oracle.com/cd/E11882_01/server.112/e17118/sql_elements006.htm#SQLRF51109)的一些變體,並將數組參數綁定到'insert'語句。 – ThinkJet

+1

AnyDac的幫助[關於一個主題和[here](http:// docs。)的[解釋](http://www.da-soft.com/anydac/docu/frames.html?frmname=topic&frmfile=Array_DML.html) oracle.com/cd/B28359_01/appdev.111/b28395/oci05bnd.htm#sthref584)是Oracle文檔中的一些信息。 – ThinkJet