SQL Server和SqlDataReader - Trillion Records - Memory

Bud*_*Joe 6 .net sql-server ado.net datareader sqldatareader

我从来没有试过这个 - 所以我不知道我是否会遇到内存问题.

但是SqlDataReader可以读取万亿条记录吗?这一切都是正确的流?我对SQL/TDS协议的内容有点了解.

更新 翻译万亿意味着非常大的数字.我可能应该说十亿或一亿.

Rem*_*anu 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和交易的问题和限制,它们非常微妙且反直觉.

  • 客户端中冗长的处理将阻止服务器.您的查询仍将一直执行,并且当通信管道填满时,服务器必须暂停它.查询消耗工作者(如果它具有并行计划,则消耗更多),并且工作是服务器中非常稀缺的商品(它们大致等同于线程).您不会承担许多客户自己处理大量结果集的麻烦.

  • 交易规模.在一次交易中处理一万亿条记录永远不会奏效.日志必须增长以适应整个事务,并且不会截断并重用VLF,从而导致巨大的日志增长.

  • 恢复时间.如果处理在第999亿条记录中失败,它将不得不回滚所有已完成的工作,因此将需要另外"12"天才能回滚.


Jon*_*eet 10

是的,那会流......但我认为你不应该真的尝试这样做.

如果你能读到每秒一百万条记录(对我来说听起来不太可能),你仍然需要12天的时间来阅读一万亿条记录...这样做有很多工作可能会导致中途失败.

现在我意识到你可能真的不想读取万亿条记录,但我的观点是,如果你能将你的"大量"工作分成逻辑批次,那么这可能是一个好主意.