C# ODP.NET数组绑定返回/输出参数性能

C# ODP.NET数组绑定返回/输出参数性能,c#,performance,oracle,odp.net,executenonquery,C#,Performance,Oracle,Odp.net,Executenonquery,我使用的一些旧代码使用了OracleDataAdaper.Update(DataSet)。如果我调用一个测试存储过程(只有输入参数),插入20000行大约需要24秒。我需要改进这一点,所以我转而使用数组绑定。使用数组绑定ExecuteNonQuery()插入相同的20000行不到3秒钟!这是一个巨大的性能改进,我还避免创建昂贵的数据集 但是,我遇到了存储过程的问题,这些存储过程具有OUT参数或返回值的函数 使用OracleDataAdaper.Update(DataSet)通过具有OUT参数的存

我使用的一些旧代码使用了
OracleDataAdaper.Update(DataSet)
。如果我调用一个测试存储过程(只有输入参数),插入20000行大约需要24秒。我需要改进这一点,所以我转而使用数组绑定。使用数组绑定
ExecuteNonQuery()
插入相同的20000行不到3秒钟!这是一个巨大的性能改进,我还避免创建昂贵的数据集

但是,我遇到了存储过程的问题,这些存储过程具有OUT参数或返回值的函数

使用
OracleDataAdaper.Update(DataSet)
通过具有OUT参数的存储过程插入相同的20000行大约需要26秒,这比没有OUT参数慢2秒或8%,这还不错
但是使用数组绑定调用相同的存储过程会导致
ExecuteNonQuery()
运行15分钟!这比w/o OUT参数慢300%


对于可变长度类型(即VARCHAR2)的所有输出/输入/返回参数,我将
OracleParameter.ArrayBindSize
属性设置为
int[numorrows]
,所有值都设置为类型的最大值(即VARCHAR2的4000)

我的测试存储过程如下所示(在现实生活中,我可能返回一个序列号):


我使用ODP.NET Oracle.DataAccess v4.112.3.0,但我非常确定它不是特定于版本的

是否有人在数组绑定参数方面遇到过类似的问题?我是否需要为OUT/return参数设置另一个属性以加快速度


我希望实现的是提高性能,而不必在数据库端进行更改。也许使用PLSQLAssociationArray可以加快速度(我还没有尝试过),但这需要对预先存在的存储过程进行太多的更改。

结果表明,ODP.NET没有提供一种通过数组绑定调整
ExecuteNonQuery()
的“获取大小”的方法。所以,当存储的proc包含OUT参数(或者函数有RETURN参数)时,Oracle会将每个项的结果分别发送回调用方。这会导致大量的网络开销,并显著降低过程的速度

使用OracleDataAdapter.Update(DataSet)时,执行结果会成批发送,从而降低网络开销


当没有OUT参数时,使用
ExecuteNonQuery()
比使用
OracleDataAdapter要快得多。更新(数据集)

结果表明,ODP.NET没有为
ExecuteNonQuery()
提供通过数组绑定调整“获取大小”的方法。所以,当存储的proc包含OUT参数(或者函数有RETURN参数)时,Oracle会将每个项的结果分别发送回调用方。这会导致大量的网络开销,并显著降低过程的速度

使用OracleDataAdapter.Update(DataSet)时,执行结果会成批发送,从而降低网络开销


当没有OUT参数时,使用
ExecuteNonQuery()
比使用
OracleDataAdapter.Update(DataSet)

快得多。是的,PL/SQL关联数组大大加快了速度。看看这里的一个例子:(对不起,代码是VB.NET,但您应该理解它)是的,PL/SQL关联数组大大加快了它的速度。请看下面的示例:(抱歉,代码是VB.NET,但您应该理解它)
    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;