代码之家  ›  专栏  ›  技术社区  ›  BuddyJoe

SQL Server和SQLDataReader-万亿条记录-内存

  •  5
  • BuddyJoe  · 技术社区  · 15 年前

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

    但sqldatareader能读取一万亿条记录吗?一切都流了,对吗?我对SQL/TDS协议所做的工作有点陌生。

    更新 把万亿翻译成非常大的数字。我可能应该说10亿或者1亿。

    3 回复  |  直到 15 年前
        1
  •  10
  •   Jon Skeet    15 年前

    是的,那会流…但我不认为你真的应该这么做。

    如果你能每秒读一百万条记录(这对我来说似乎不太可能),你仍然需要12天来读一万亿条记录…要冒半途而废的风险,这是一项艰巨的任务。

    现在我意识到你可能不会 真正地 想读一万亿条记录,但我的观点是,如果你能把大量的工作分成逻辑批,那可能是个好主意。

        2
  •  13
  •   Remus Rusanu    15 年前

    有一些细节。

    • sqldatareader通常会读取内存中的整行并缓存它。这包括任何blob字段,因此您最终可以在内存中缓存几个2GB字段(xml、varbinary(max)、varchar(max)、nvarchar(max))。如果这些字段是一个问题,那么您必须在 CommandBehavior.SequentialAccess ExecuteReader 并使用特定于sqlclient类型的流式处理功能,如 SqlBytes.Stream .

    • 连接正忙,直到SQLDataReader完成。这会产生事务性问题,因为您将无法在同一个Transaciton中对数据库进行任何处理,因为连接正忙。尝试打开不同的连接并注册同一个事务将失败,因为禁止回送分布式Transaciton。这个颜色是要用的 MARS .你可以通过设置 MultipleActiveResultSets=True 在连接上。这允许您在 相同的 数据读取器仍处于活动状态时的连接(典型的获取过程获取循环)。仔细阅读Christian Kleinerman's的链接,确保您了解火星和交易的问题和限制,它们非常微妙和反直觉。

    • 客户机中的长时间处理将阻塞服务器。您的查询将一直在执行,当通信管道填满时,服务器将不得不挂起它。查询使用 worker (如果它有平行的平面图,则更多)和工作是 非常 服务器中的稀缺商品(它们大致等同于线程)。 你不能让许多客户从容不迫地处理巨大的结果集。

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

    • 恢复时间。如果处理在999亿记录时失败,它将不得不回滚所有已完成的工作,因此只需“12”天就可以回滚。

        3
  •  1
  •   Cade Roux    15 年前

    是的-这可能需要一段时间(只要您的SQL没有做任何愚蠢的事情,试图获取快照或其他),但如果您的服务器可以流出来,则SQLDataReader不应该有内存使用问题。