【问题标题】:How to stream resultset with MySQL .net connector for large dataset如何使用 MySQL .net 连接器为大型数据集流式传输结果集
【发布时间】:2014-11-02 03:57:07
【问题描述】:

我需要从 MySQL 服务器检索大型数据集进行处理。 我为此使用 MySQL .net 连接器,因为使用数据的应用程序是用 F# 编写的。数据集太大而无法放入内存,因此我希望避免将原始数据完全保存在内存中,并在数据从数据库服务器流入应用程序时对其进行操作。

我读到这可以通过使用 JDBC API 中的 ResultSet 属性来完成,例如 Streaming large result sets with MySQLhttp://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html,但我还没有找到类似的 .Net API。

到目前为止,我的搜索主要是通过http://dev.mysql.com/doc/connector-net/en/connector-net-programming.html 上的 MySQL 文档进行的,但这并没有发现任何东西(至少,对我来说没有什么明显的)。

我怎样才能完成我想做的事情?

更新:

关于我的局限性的一些细节。

我只有对数据源的读取权限,因为它是由第三方管理的,所以在服务器端进行任何更改都是不行的。

这是我推送到服务器的查询的样子:

SELECT
      SID.dwsi_store AS 'store'
     ,SID.dwsi_transaction_date AS 'transactionDate'
     ,SID.dwsi_transaction AS 'transaction'
     ,SID.dwsi_item AS 'sku'
     ,C.dwcl_class AS 'clss'
     ,D.dwde_department AS 'department'
 FROM
     dw_sls_item_dtl SID
 JOIN
     dw_item I
 JOIN
     dw_class C
 JOIN
     dw_department D
 ON
         SID.dwsi_store = I.dwin_store
     AND SID.dwsi_item = I.dwin_item_number
     AND I.dwin_store = C.dwcl_store
     AND I.dwin_class = C.dwcl_class
     AND I.dwin_store = D.dwde_store_number
     AND I.dwin_department = D.dwde_department
 WHERE
         SID.dwsi_transaction_date >= '2007-03-01'
     AND SID.dwsi_store BETWEEN '2' AND '8'
     AND NOT C.dwcl_class = ''
     AND NOT C.dwcl_class_name LIKE('%CCL''d%')
     AND D.dwde_department BETWEEN '10' AND '92'

虽然我可以通过参数化 where 子句并一次检索一个日期的数据来手动翻阅数据,但如果 MySQL 连接器有更优雅的解决方案可用,我不希望这样做.

更新

这是调用数据库服务器的代码。它使用返回 DbDataReader 的 ExecuteReader 方法。现在我想起来了,问题可能是我正在将所有内容读入一个序列而不对其进行操作。看来这个问题与我如何实现阅读器有关,而不是阅读器本身。

use cn = new MySqlConnection(cs)
use cmd = new MySqlCommand(sql,cn)
cmd.CommandType = CommandType.Text |> ignore
cn.Open()
use reader = cmd.ExecuteReader()
while reader.Read() do
    yield { store = unbox (reader.["store"])
            transactionDate = unbox (reader.["transactionDate"])
            transaction = unbox (reader.["transaction"])
            sku = unbox (reader.["sku"]) 
            clss = unbox(reader.["clss"])
            department = unbox(reader.["department"])} }

【问题讨论】:

  • 也许您应该对查询进行分页并获得每个部分的结果,而不是将所有内容加载到内存中。你能做到吗?
  • @FelipeOriani,这是个好主意,但如果有任何替代方案,我宁愿不这样做。请参阅我的问题中的更新。

标签: mysql .net f# ado.net


【解决方案1】:

我认为您正在寻找 DbDataReader 的派生类;可能是 OdbcDataReader 或 OleDbDataReader。这些类提供对结果集的只进访问。有关详细信息,请参阅以下链接:

http://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.110).aspx(“在检索大量数据时,DataReader 是一个不错的选择,因为数据没有缓存在内存中。”)

http://msdn.microsoft.com/en-us/library/system.data.common.dbdatareader(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/system.data.odbc.odbcdatareader(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdatareader(v=vs.110).aspx

【讨论】:

  • 我使用的是 dbdatareader,但我突然想到问题是我将所有结果推送到一个可枚举的对象中,而不是在它们进入时对其进行操作。问题出在我的结束,而不是一直在连接结束。不过感谢您的回复,它帮助我了解了我做错了什么。
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多