我有没有任何索引的 SQL Server 表,我无法添加它们。该表中有数百万条记录,由于内存不足,我无法通过单个查询获取所有记录。
如何获取小部分的所有记录 - 例如每部分 100 条记录?
我有没有任何索引的 SQL Server 表,我无法添加它们。该表中有数百万条记录,由于内存不足,我无法通过单个查询获取所有记录。
如何获取小部分的所有记录 - 例如每部分 100 条记录?
您如何尝试阅读记录?如果你使用 a SqlDataReader
,那么你不应该有任何内存不足的问题。
const string QUERY = "SELECT * FROM MyTable";
using (var conn = new SqlConnection(CONNECTION_STRING))
{
using (var cmd = new SqlCommand(QUERY, conn))
{
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// Use properties and methods of the reader to access the current row
}
}
}
}
这会在数据库连接中一次传递一行。该连接将为您进行缓冲,从数据库中获取多行,并一次将它们传递给您。
这是可以将游标用于其实际目的的罕见情况之一。
您可以创建一个 statiс 游标(它将创建表数据的副本,但在服务器的临时数据库中而不是在客户端,并对其进行排序)并浏览此游标。
一种解决方案是 - 将我需要转储的所有表选择到带有标识列的临时表中。这是......可接受的解决方案,因为我有单独的应用程序和数据库服务器,并且数据库服务器有足够的内存。但可能有更有效的解决方案?
正如 Quassnoi 已经建议的那样,一种解决方案是使用服务器端光标。这样做的缺点是它必须是静态游标,这意味着将在 tempdb 中创建整个表的副本。
另一种解决方案是以面向流的方式逐行处理客户端(即客户端游标):
using(SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (rdr.Read())
{
-- process one row here
}
}
通过这种方式,您可以处理大行集,而不会耗尽所有客户端内存。