我正在使用 .Net 4.0 和 SQL Server 2008 R2。
我正在运行一个大型 SQL 选择查询,它返回数百万个结果并且需要很长时间才能完全运行。
有谁知道我怎样才能只读取查询返回的部分结果而不必等待整个查询完成?
换句话说,我想在查询仍在运行并获得下一个结果时读取第一个 10,000 个记录块。
我正在使用 .Net 4.0 和 SQL Server 2008 R2。
我正在运行一个大型 SQL 选择查询,它返回数百万个结果并且需要很长时间才能完全运行。
有谁知道我怎样才能只读取查询返回的部分结果而不必等待整个查询完成?
换句话说,我想在查询仍在运行并获得下一个结果时读取第一个 10,000 个记录块。
这部分取决于查询本身是否是流式的,或者它是否在临时表中做了很多工作然后(最终)开始返回数据。在第二种情况下,除了重新编写查询之外,您不能做太多事情;但是,在第一种情况下,迭代器块通常会有所帮助,即
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-SQLExecuteQuery<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 过滤数据,因为数据库的性能比你的逻辑 leyer 好得多。
或者遵循延迟加载概念,仅在需要时才加载实际数据的 ID。