【问题标题】:.Net - Creating an On-Demand recordset rather than pulling everything into memory at once.Net - 创建按需记录集,而不是一次将所有内容拉入内存
【发布时间】:2014-02-21 14:36:27
【问题描述】:

我不知道这个标题是否有意义,但我的情况如下:

我正在编写一个 .Net 程序来查询 Oracle 数据库以获取大量历史记录(大约 2 年的日常数据),并且需要从此返回的查询创建一个分隔的文本文件以发送给客户端填充他们的新数据库(最终文件大小约为 4gb)。

我目前的代码基本如下:

Dim strSQLQuery as string = (My query to get all the data)
Dim cmd = New OracleCommand(strSQLQuery, conn)
...
Using Reader As OracleDataReader = cmd.ExecuteReader()
    ... write to text file ...
End Using

这段代码很好用,但我的问题是查询返回了如此庞大的记录集,所以我担心cmd.ExecuteReader() 语句的内存不足。

我的问题是,.Net 中是否有任何方法可以处理整个查询并一次返回整个记录集,所以让记录集以更大的块或类似的方式返回?

当然,一种解决方案是分解查询本身(我可以这样做),但我也很想知道在沿着这条路线前进之前 .Net 中是否已经存在更好的解决方案......

此外,虽然这段代码是用 VB 编写的,但我对 VB 或 C# 的解决方案同样满意。

谢谢!!!

【问题讨论】:

  • cmd.ExecuteReader() 不应一次提取所有数据。您将返回一个OracleDataReader,然后在您逐行阅读时将数据流式传输给您。您是否在 ExecuteReader 或后续读取时内存不足?
  • @NikolaRadosavljević,也许我弄错了......我还没有在完整的日期范围内运行它。但即使我运行了一个月,发生的事情是从数据库中查询数据需要 非常 很长时间,所以我认为它正在查询并返回所有数据......是那个绝对不正确的假设??
  • 是什么让你觉得结果一下子就回来了? Reader 使用 Read() 抓取一行。实际上,它一次打包一组行是为了提高效率,而不是整个查询。
  • 我真的很抱歉 - 我想我(在不知不觉中)已经在使用正确的工具来完成这项工作......感谢您的澄清!!!

标签: c# sql .net vb.net oracle


【解决方案1】:

OracleDataReader 不会将所有记录放入内存中。查看 Fetchsize 属性,它控制实际缓存的记录数量,直到我们需要第二次往返数据库。

如果您希望 Oracle 更快地返回行,例如,您可以尝试

/*+ FIRST_ROWS(n) */

在您的查询中提示与

/*+ ALL_ROWS */ 

提示您是否可以等待所有数据。

【讨论】:

  • 我真的很抱歉 - 我想我(在不知不觉中)已经在使用正确的工具来完成这项工作......感谢您的澄清!!!
【解决方案2】:

OracleCommand.ExecuteReader 方法不会预先加载所有数据。它只为您提供OracleDataReader,然后您可以使用它来加载数据。没有指定OracleDataReader是否预先加载数据,以及加载多少,但它并没有直接拉入查询请求的所有数据。

当您有大量数据时,您甚至可以指定读取器只应从单行中逐个字段地提取数据。这是使用CommandBehavior.SequentialAccess 完成的。

【讨论】:

  • Nikola,非常感谢您澄清我的无知!迪特已经回答了,当你发布我可以接受的东西时,我已经接受了他的回答,但我真的非常感谢你对此的澄清和解释!!!
  • 没问题。 SO 是一个图书馆,很高兴能参考一些信息,所以我还是提交了。
猜你喜欢
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 2016-05-05
相关资源
最近更新 更多