处理大型SQL select查询/读取SQL数据块
本文关键字:SQL 读取 数据 查询 大型 select 处理 | 更新日期: 2023-09-27 17:52:15
我使用。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-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。