从 ODBC 读取器读取 Oracle CLOB 数据非常慢

Reading Oracle CLOB data from ODBC reader is super slow

我们正在使用 C# 和 .Net 4.5 从 Oracle 数据库下载数据。

values[]是对象数组; reader 是 ODBC 读取器,它与 Oracle 数据库 table 和 CLOB 数据建立了开放连接。

相关代码如下:

if (reader.Read())
{   //Download and save the values
    for (int x = 0; x < reader.FieldCount; x++)
    {   //Populate all the values
        values[x] = reader[x];  //this line seems to cause execution to hang
    }
    //
    //blah blah blah
    //
}

C#代码好像挂在了values[x] = reader[x];.

线上

我们将读取的行中的每一列分配给一个特殊的对象数组,因为我们需要稍后对该数据执行单独的操作,而现在不必担心数据类型。

问题在于,当 table 遇到一个很大 (> 28,000) 的 Oracle CLOB 数据列时,该行似乎永远不会完成。

如果我们从 odbc 读取器读取的内容中删除 CLOB 列,一切都会完美无缺。

问题:

  1. 为什么会这样?数组赋值不是应该比较快吗?
  2. 有哪些可能的变通方法可以让我们在下载的数据中保留 CLOB 列?我们 需要将 ODBC 阅读器保持为通用 ODBC 阅读器(而不是特定于 Oracle)。

应用程序已编译,必须保持 32 位。

谢谢!

除非有真正令人信服的理由使用 ODBC,否则最好使用 ODP.net 或托管 ODP.net。虽然我不能 100% 肯定地说 ODBC 是您的问题,但我可以告诉您我已经多次将 .NET 与 LOB 一起使用,没有问题,使用 ODP.net。我还可以告诉你,Microsoft 的 Oracle 驱动程序(已删除)引起了无数神秘问题,其中大部分与性能有关。例如,查询 1 工作正常,但用绑定变量替换文字会导致执行延迟 15 秒。使用 ODP.net,延迟消失。我的猜测是ODBC可能有类似的神秘问题。

ODP.net(或 DevArt dotConnect)是我所知道的仅有的两个使 .NET 能够利用 OCI 的工具,OCI 具有批量插入和更新等强大功能。 OCI 可能有更好的方法来处理大型 LOB。您是否有必须使用 ODBC 的令人信服的理由?

问题出在 CLOB 类型上! 将其转换为 varchar 并且性能还可以:

改变

select clob from table 

至 2 次选择

select DBMS_LOB.SUBSTR(clob,4000,1) from table where length(clob)<= 4000;
select clob from table where length(clob)> 4000;

很容易验证 - 小的 clob 列的性能很慢,但转换为 varchar 可以解决问题![​​=13=]

问题是每个 CLOB 列提取都会发出 2 次从客户端到服务器的额外网络往返!

通常情况下,多行需要一次净往返

添加LONGDATACOMPAT=1;在您的字符串连接上:

string conn = @"DSN=database;UID=user;PWD=password;LONGDATACOMPAT=1;";