我的任務是從Oracle數據庫調用存儲過程。 存儲過程定義如下:如何提高存儲過程的執行性能?
CREATE OR REPLACE PROCEDURE my_st_proc
(pname IN VARCHAR2, pdate IN date, o_rc OUT sys_refcursor, o_flag OUT number);
所以它需要兩個輸入參數,返回兩個輸出參數,其中之一是一個光標。 使用以下代碼測試pl \ sql developer中的性能時,它會在2-3秒內完成。
DECLARE
pname varchar2(300) := 'john doe';
pdate date := to_date('01/01/1900','dd/mm/yyyy');
o_flag number;
o_data sys_refcursor;
--MyRec describes the fields, returned by the cursor
TYPE MyRec IS RECORD
(cAccount VARCHAR2(20), cBalance number, cDate date, cCurr varchar2(8));
rec MyRec;
BEGIN
my_st_proc(pname,pdate,o_data,o_flag);
dbms_output.put_line(o_flag);
LOOP
FETCH o_data INTO rec;
EXIT WHEN o_data%NOTFOUND;
dbms_output.put_line(
rec.cAccount||','||rec.cBalance||','||rec.cDate||','||rec.cCurr);
END LOOP;
close o_data;
END;
但是,當我通過ODP.Net調用存儲過程時,需要多達兩秒的時間才能完成(3 - 5秒)。
const string p_name = "pname";
const string p_date = "pdate";
const string p_data = "o_data";
const string p_flag = "o_flag";
using (var connection = new OracleConnection("my connection"))
{
var command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "my_st_proc";
var pname = command.Parameters.Add(p_name, OracleDbType.Varchar2);
pname.Direction = ParameterDirection.Input;
var pdate = command.Parameters.Add(p_date, OracleDbType.Date);
pdate.Direction = ParameterDirection.Input;
command.Parameters.Add(p_data, OracleDbType.RefCursor).Direction =
ParameterDirection.Output;
var pflag = command.Parameters.Add(p_flag, OracleDbType.Int32);
pflag.Direction = ParameterDirection.Output;
if (command.Connection.State != ConnectionState.Open)
command.Connection.Open();
command.Parameters[p_name].Value = name;
command.Parameters[p_date].Value = date;
DateTime bdate = DateTime.Now;
command.ExecuteNonQuery();
if (((OracleDecimal)command.Parameters[p_flag].Value).ToInt32() == 1)
{
}
else
{
using (var oreader = command.ExecuteReader())
{
if (oreader != null)
{
try
{
while (oreader.Read()){ }
}
finally
{
oreader.Close();
}
}
}
}
MessageBox.Show(DateTime.Now.Subtract(bdate).ToString());
}
最耗時的代碼行似乎是
command.ExecuteNonQuery();
和
command.ExecuteReader()
由遊標返回的行數不超過10 - 15,足以幾並通過閱讀器閱讀它們需要幾毫秒;所以我想這不是FetchSize
或RowSize
問題。
在這種情況下,我可以做些什麼來提高ODP.Net的性能?
感謝您的回覆。我已經相應地改變了'CommandType'和'CommandText'。然而你是對的,它並沒有提高性能。至於你的第一個想法,它可能是這種情況,儘管我在一個「OracleConnection」中執行該過程以保持它打開。第一個和以下所有調用之間有區別。第一個顯然更長。 – horgh
但以下所有調用仍會持續更長時間,然後從pl sql開發人員工具調用 – horgh
我同意這可能與建立連接有關。通過連接執行循環中的代碼。在循環之外打開,並在循環中(池中應該給出相同的結果)。 –