2015-01-05 61 views
1

我们正在使用C#和.Net 4.5从Oracle数据库下载数据。从ODBC读取器读取Oracle CLOB数据超级慢

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];

我们将行读取中的每一列都分配给一个特殊的对象数组,因为我们以后需要对这些数据做单独的事情,而不必担心此刻的数据类型。

问题在于,当一个表使用大(> 28,000)的Oracle CLOB数据列命中时,该行永远不会完成。

如果我们从odbc阅读器读取的内容中删除CLOB列,那么所有内容都可以正常工作。

问题:

  1. 为什么会变成这样?不应该阵列分配比较快?
  2. 什么是一些可能的解决方法,所以我们可以保持CLOB列在下载的数据?我们 需要保持ODBC阅读器作为通用的ODBC阅读器(而不是特定于Oracle)。

该应用程序已编译并且必须保持32位。

谢谢!

回答

0

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

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

+0

Thanks @Hambone。我们使用ODBC的迫切理由是因为这个应用程序可以针对众多数据库运行,而且我们不希望为每个数据库专门编写代码。例如,这个应用程序可以查询SQL Server,Oracle,使用32位ODBC Tibco驱动程序的旧数据库以及PostGre数据库。代码现在可用于除最近的Oracle CLOB数据之外的所有应用程序。鉴于有限的资源,很容易弄清楚为什么会发生这种情况。 –

+0

我打算把它作为现在的答案。不幸的是,我们目前没有时间/资源来测试这个理论并且专门使用ODP编写代码,但是如果我们希望能够回到并更新它。 :-) –

1

它是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列,WEEL慢,但铸造到varchar解决问题!

问题是,每一个CLOB列提取都会从客户端向服务器发出2个额外的净往返行程!

通常你有几行

一个净往返
0

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

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