处理大型SQL select查询/读取SQL数据块

本文关键字:SQL 读取 数据 查询 大型 select 处理 | 更新日期: 2023-09-27 17:52:15

我使用。net 4.0和SQL server 2008 R2。

我正在运行一个大的SQL选择查询,它返回数百万个结果,需要很长时间才能完全运行。

有没有人知道我如何才能读取查询返回的一些结果,而不必等待整个查询完成?

换句话说,我想在查询仍然运行并获得下一个结果的同时读取第一个由10,000个记录块。

处理大型SQL select查询/读取SQL数据块

这部分取决于查询本身是否是流,或者它是否在临时表中做了大量工作,然后(最终)开始返回数据。在第二种场景中,除了重写查询之外,您不能做太多事情;然而,在第一种情况下,迭代器块通常会有所帮助,即

public IEnumerable<Foo> GetData() {
     // not shown; building command etc
     using(var reader = cmd.ExecuteReader()) {
         while(reader.Read()) {
             Foo foo = // not shown; materialize Foo from reader
             yield return foo;
         }
     }
}

这现在是一个流迭代器-你可以在它上面foreach,它将从传入的TDS数据中实时检索记录,而不需要首先缓冲所有数据。

如果你(也许是明智的)不想编写自己的物化代码,有工具可以为你做这件事——例如,LINQ-to-SQL的ExecuteQuery<T>(tsql, args)可以轻松地完成上面的工作。

你需要使用数据分页。

SQL Server有TOP子句(SQL TOP 10 a,b,c from d)和BETWEEN:
SELECT TOP 10000 a,b,c from d BETWEEN X and Y

有了这个,我想你可以检索N行,做一些部分处理,然后加载下一个N行,等等。

这可以通过实现多线程解决方案来实现:一个将检索结果,而另一个将异步等待数据,它将做一些处理。

如果你真的需要处理数百万条记录,为什么不每轮加载10,000条记录,然后加载下一个10,000条呢?如果没有,可以考虑在加载数据之前使用DBMS来过滤数据,因为数据库上的性能比逻辑层要好得多。

或者遵循延迟加载的概念,只在需要时才加载实际数据的id。