3

与 MS SQL Server 相比,我在从 OracleDataReader 对象中读取数据时遇到了一些糟糕的性能。它几乎慢了 10 倍,这是不可接受的。

下面是两个测试都使用的一些示例测试代码。从 OracleDataReader 读取数据的最佳方法是什么,有没有比下面显示的更好的方法?

我很难相信 ODP.Net 甚至无法与 SqlClient 相提并论。

更新:我已将问题缩小到获取文本字段。出于某种原因,ODP.Net 在这方面很糟糕。任何想法如何解决它?

void ReadData(System.Data.IDataReader dr, int maxRows)
 {
     ArrayList rows = new ArrayList(maxRows > 0 ? maxRows : 1000);

     object[] row;

     int rowsRead = 0;
     while (dr.Read() && ((maxRows == -1) || (rowsRead++ < maxRows)))
     {
         row = new object[dr.FieldCount];
         dr.GetValues(row);

         rows.Add(row);
     }
     rows.Clear();
 }

笔记):

  • 尝试使用 FetchSize 进行试验,并没有遇到太大的不同

  • 查询运行时间不是这里的问题,只有数据检索。

  • 两个数据库上的数据结构是相同的。

  • 尝试了具有相似结果的 DataAdapter/DataSet 组合。

4

1 回答 1

4

我们实际上已经将此问题追溯到使用 CLOB 列来存储 nvarchar(MAX) 类型的字符串数据。

Oracle 承认他们的 OCI 软件在处理 CLOB 时存在问题。默认情况下,他们尝试以与检索非常大的 BLOB 相同的方式检索 CLOB。他们设置指针,尝试进行分页等等。当然,当涉及到常规的 ~200 字符文本字段时,这种默认行为会降低性能。实际上,您可以通过将 LOBFetchSize 设置为 -1 来关闭此行为。这样,它将在一次往返中获取 CLOB 的内容。然后事情开始发展,你会得到非常好的表现。

即使这样,我们仍然有问题。我们确认了 11.2 版本之前的 OCI 软件中存在内存泄漏和内存引用错误。但是 11.2 似乎在 32 位和 64 位场景中都可以正常工作。

因此,将 LOBFetchSize 设置为 -1 是此处的性能修复程序。

于 2010-10-20T13:30:28.887 回答