2013-12-09 43 views
1

我使用的一些舊代碼使用OracleDataAdaper.Update(DataSet)。如果我調用測試存儲過程(只有輸入參數),則需要大約24秒才能插入20,000行。我需要改進,所以我切換到使用數組綁定。使用數組綁定ExecuteNonQuery()需要3秒鐘才能插入相同的20,000行!這是一個巨大的性能改進,我也避免了創建昂貴的數據集。ODP.NET數組綁定返回/ OUT參數性能

但是,我遇到了具有OUT參數或函數返回值的存儲過程的問題。

通過使用OracleDataAdaper.Update(DataSet)具有OUT參數的存儲過程插入相同的20,000行需要大約26秒 - 這比w/o OUT參數慢2秒或8% - 不壞。
但是使用數組綁定調用相同的存儲過程導致ExecuteNonQuery()運行15分鐘!這比w/o OUT參數慢300%!


對於所有OUT/IN OUT /可變長度型(即VARCHAR2)的返回參數,我設置OracleParameter.ArrayBindSize屬性int[numOfRows]設置爲最大值爲所有類型值(即4000 VARCHAR2)。

我測試的存儲過程是這樣的(在現實生活中,我可以返回一個序列號):

PROCEDURE INSERT_TEST(
     p_key   VARCHAR2, 
     p_id    NUMBER, 
     p_dt    DATE, 
     p_unique_key OUT VARCHAR2) 
     AS 
     BEGIN 
     INSERT INTO T_TEST_DAL(
         UNIQUE_KEY, 
         NUM_ID, 
         DT_VAL) 
     VALUES (
       p_key, 
       p_id, 
       p_dt) 
     RETURNING UNIQUE_KEY 
      INTO p_unique_key; 
    END INSERT_TEST; 

我使用ODP.NET Oracle.DataAccess v4.112.3.0,但我很確定它不是版本特定的。

有沒有人面臨數組綁定輸出參數類似的問題?我是否需要爲OUT /返回參數設置另一個屬性以加快速度?

我希望能夠完成的是提高性能,而無需在數據庫端進行更改。也許使用PLSQLAssociativeArray會加快速度(我還沒有嘗試過),但這需要對預先存儲的特效進行太多更改。

+0

是的,PL/SQL關聯數組加速了很多。看看這裏的例子:http://stackoverflow.com/questions/20401050/is-there-a-way-to-pass-a-set-of-values-as-a-parameter-in-an- oracle-sql-statement/20405447#20405447(對不起的代碼是VB.NET,但你應該理解它) –

回答

0

原來,ODP.NET沒有提供一種方法來調整數組綁定的ExecuteNonQuery()的「獲取大小」。所以當一個存儲過程包含一個OUT參數(或者函數具有RETURN參數)時,Oracle會將每個項目的結果分別發回給調用者。這會導致大量網絡開銷並顯着降低流程速度。

使用OracleDataAdapter.Update(DataSet)時,執行結果將分批發送,從而降低網絡開銷。

當沒有OUT參數時,使用ExecuteNonQuery()而不是OracleDataAdapter.Update(DataSet)要快得多。