2011-12-01 71 views
1

當執行DML時,我有兩個關於PL/SQL腳本性能的問題。 Ofcourse的EXECUTE IMMEDIATE是最慢的一個這就是爲什麼我們有forallbulk插入等我的問題是在程序/函數中與高效的DML相關的問題

  1. 我不得不操縱3個不同的表中的數據。 Table1(插入數據),Table2(更新數據)和Table3刪除數據。所有這些都將基於使用遊標獲取的值完成。問題是在這裏會更有效率?
    • 將這些陳述中的每一個置於個別Forall區塊?即
fetch cursor 
loop 
    forall loop for table 1 
    forall loop for table 2 
    forall loop for table 3 
end loop 

OR

  • 一個全局環和執行這些statments在該循環即
fetch cursor loop 
    for i IN array.count 
    loop 
     3 statements for DML 
    end loop end loop 

現在我的第二個問題

  1. 什麼是刪除循環記錄的有效途徑?我通過光標獲取要刪除的記錄的值。現在什麼是刪除它們的有效方法?

PS: Execuse我格式化

回答

4

最有效的辦法是寫三個SQL語句,假設從遊標讀取的數據是在該程序運行的時間週期穩定

INSERT INTO table1(list_of_columns) 
    <<your SELECT statement>> 

UPDATE table2 
    SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>) 
WHERE EXISTS(<<your SELECT statement joined to table2>>); 

DELETE FROM table3 
WHERE EXISTS(<<your SELECT statement joined to table3>>); 

如果SELECT語句有可能在三個DML語句中返回不同的結果,那麼接受使用遊標,將數據批量收集到PL/SQL集合以及循環以確保收集結果一致。如果這就是你正在做的事情,那麼有三條語句會更有效率,因爲SQL和PL/SQL引擎之間的上下文移動較少。

在循環中刪除記錄的有效方法是什麼?我通過光標獲取要刪除的記錄的值。現在什麼是刪除它們的有效方法?

我不確定我是否理解這個問題。難道你只是做一個FORALL循環就像你爲INSERTUPDATE

FORALL i IN l_array.first .. l_array.last 
    DELETE FROM some_table 
    WHERE some_key = l_array(i); 

還是想提出一個不同的問題?

+0

這很有幫助。關於'FORALL',我相信* ORACLE10G *沒有'bulk' /'bind'選項。它給了錯誤。到目前爲止,oracle 10 g我被迫選擇了'FOR'循環。關於刪除記錄。提取'ROWID'來刪除記錄或使用'key'比較會更好嗎? –

+0

@ x.509 - Oracle 10g當然支持帶有DELETE的'FORALL'以及批量綁定。如果您遇到錯誤,您是否可以編輯您的問題以發佈您正在使用的代碼以及發生的錯誤。使用'ROWID'可能比使用'DELETE'上的一個鍵稍微快一些,但是你可能會在SELECT上失去這個時間,因爲大概你需要鍵而不是'ROWID'來執行'INSERT'和' UPDATE'。 –

+0

賈斯丁,我有一個錯誤'福爾',但我想通了。 http://www.oracle-developer.net/display.php?id=410 ...現在我很擔心表演。 –