我从未尝试过 - 所以我不知道是否会遇到内存问题。
但是SqlDataReader可以读取一万亿条记录吗?这一切都是正确的流?我对SQL / TDS协议的内容有点了解。
更新 翻译万亿意味着非常大的数字。我可能应该说十亿或一亿。
答案 0 :(得分:13)
有一些细节。
SqlDataReader通常会读取内存中的整行并对其进行缓存。这包括任何BLOB字段,因此您最终可以在内存中缓存多个2GB字段(XML,VARBINARY(MAX),VARCHAR(MAX),NVARCHAR(MAX))。如果这些字段是一个问题,那么您必须将CommandBehavior.SequentialAccess传递给ExecuteReader并使用SqlClient特定类型的流功能,如SqlBytes.Stream。
连接正忙,直到SqlDataReader完成。这会产生事务性问题,因为您无法在同一个事务中对数据库中的任何处理进行处理,因为连接很繁忙。尝试打开不同的连接并注册同一事务将失败,因为禁止回送分布式事务。问题是使用MARS。您可以通过在连接上设置MultipleActiveResultSets=True
来实现此目的。这允许您在数据读取器仍处于活动状态时(在典型的fetch-process-fetch循环中)在相同的连接上发出命令。仔细阅读Christian Kleinerman的链接,确保您了解MARS和交易的问题和限制,它们非常微妙且反直觉。
客户端冗长的处理将阻止服务器。您的查询仍将一直执行,并且当通信管道填满时,服务器必须暂停它。查询消耗worker(如果它具有并行计划,则为更多),并且工作是服务器中的非常稀缺商品(它们大致等同于线程)。 对于很多客户来说,处理他们自己的裂缝处理大量结果集,你不会感到很麻烦。
交易规模。在一次交易中处理一万亿条记录永远不会奏效。日志必须增长以适应整个事务,并且不会截断并重用VLF,从而导致巨大的日志增长。
恢复时间。如果处理在第999亿条记录中失败,它将不得不回滚所有已完成的工作,因此将需要另外“12”天才能回滚。
答案 1 :(得分:10)
是的,这会流......但我认为你不应该尝试这样做。
如果你能够每秒读取一百万条记录(对我来说听起来不太可能),那么你仍然需要12天的时间来阅读一万亿条记录...这样做有很多工作可能会让你失去一半。
现在我意识到你可能不会真的想要读取万亿条记录,但我的观点是,如果你能将你的“大量”工作分成逻辑批次,那就是可能是个好主意。
答案 2 :(得分:1)
是的 - 它可能需要一段时间(只要您的SQL没有做任何傻事尝试拍摄快照或任何东西),但如果您的服务器可以将其流出,SqlDataReader不应该有内存使用问题