【发布时间】:2014-11-02 03:57:07
【问题描述】:
我需要从 MySQL 服务器检索大型数据集进行处理。 我为此使用 MySQL .net 连接器,因为使用数据的应用程序是用 F# 编写的。数据集太大而无法放入内存,因此我希望避免将原始数据完全保存在内存中,并在数据从数据库服务器流入应用程序时对其进行操作。
我读到这可以通过使用 JDBC API 中的 ResultSet 属性来完成,例如 Streaming large result sets with MySQL 和 http://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,这是个好主意,但如果有任何替代方案,我宁愿不这样做。请参阅我的问题中的更新。