从ODBC读取器读取Oracle CLOB数据非常慢
本文关键字:读取 数据 非常 CLOB Oracle ODBC | 更新日期: 2023-09-27 18:36:07
我们正在使用 C# 和 .Net 4.5 从 Oracle 数据库下载数据。
values[]
是一个对象数组;读取器是 ODBC 读取器,与包含 CLOB 数据的 Oracle 数据库表建立打开连接。
以下是相关代码:
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];
行上。
我们将读取的行中的每一列分配给一个特殊的对象数组,因为我们稍后需要对该数据执行单独的操作,并且目前不必担心数据类型。
问题在于,当一个表被一个很大的Oracle CLOB数据列(>28,000)击中时,该行似乎永远不会完成。
如果我们从 odbc 阅读器读取的内容中删除 CLOB 列,一切都可以完美运行。
问题:
- 为什么会这样?数组分配不应该相对较快吗? 有哪些
- 可能的解决方法,以便我们可以将 CLOB 列保留在下载的数据中?我们需要将 ODBC 读取器保留为通用 ODBC 读取器(而不是特定于 Oracle 的)。
应用程序已编译,并且必须保持 32 位。
谢谢!
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;
这很容易验证 - 小柱子的性能很慢,但铸造到 varchar 解决了问题!
问题是每个 CLOB 列提取都会发出从客户端到服务器的额外 2 次净往返!
通常,几行将有一个净往返
除非有真正令人信服的理由使用 ODBC,否则最好使用 ODP.net 或托管 ODP.net。 虽然我不能 100% 肯定地说 ODBC 是您的问题,但我可以告诉您,我已经多次将 .NET 与 LOB 一起使用而没有问题,使用 ODP.net。 我还可以告诉你,甲骨文的Microsoft驱动程序(已弃用)引起了无数的神秘问题,其中大部分都与性能有关。 例如,查询 1 工作正常,但将文本替换为绑定变量会导致执行时的性能延迟 15 秒。 使用 ODP.net,延迟消失。 我的猜测是,ODBC可能有类似的神秘问题。
ODP.net(或DevArt dotConnect)是我所知道的仅有的两个工具,使.NET能够利用OCI,OCI具有批量插入和更新等强大功能。 OCI 可能具有处理大型 LOB 的更好方法。 是否有令人信服的理由必须使用 ODBC?
在字符串连接上添加 LONGDATACOMPAT=1:
string conn = @"DSN=database;UID=user;PWD=password;LONGDATACOMPAT=1;";