OracleDataReader 性能不佳

发布于 2024-08-20 22:04:03 字数 867 浏览 4 评论 0原文

与 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 组合,结果相似。

I'm experiencing some terrible performance with reading data off the OracleDataReader object compared to MS SQL Server. It is almost 10 times slower, which is unacceptable.

Below is some sample test code that both tests use. What's the most optimum way to read data from OracleDataReader, is there a better way than shown below?

I'm having hard time believing that ODP.Net can't even compare to SqlClient.

UPDATE: I've narrowed down the problem to fetching of text fields. For some reason ODP.Net is terrible at this. Any ideas how to fix it?

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();
 }

Note(s):

  • Tried experimenting with FetchSize, didn't experience a big difference

  • Query run times aren't the issue here, only the data retrieval.

  • The data structures on both databases are identical.

  • Tried DataAdapter/DataSet combo with similar results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌路黄昏 2024-08-27 22:04:03

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

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

尽管如此,我们仍然遇到问题。我们确认了 11.2 版本之前的 OCI 软件存在内存泄漏和内存引用错误。但 11.2 似乎在 32 位和 64 位场景中都能正常工作。

因此,将 LOBFetchSize 设置为 -1 可以解决性能问题。

We have actually traced this issue down to the use of CLOB columns to store nvarchar(MAX) type of string data.

Oracle has admitted that their OCI software has issues dealing with CLOBs. By default they try to retrieve the CLOB the same way they'd retrieve a very large BLOB. They setup pointers, try to do paging and etc. Of course, this default behavior kills performance when it comes to a regular ~200 char text field. You actually turn this behavior off by setting LOBFetchSize to -1. This way it'll grab the contents of the CLOBs in one round trip. Then things start flying and you get very good performance.

Even with this though we continued to have issues. We confirmed memory leaks and memory reference errors in the OCI software prior to version 11.2. But 11.2 seems to be working fine in both 32 and 64 bit scenarios.

So setting the LOBFetchSize to -1 was the performance fixer here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文