SQLDataReader如何处理真正大的查询?

实际上我不确定标题是否准确描述了这个问题,但我希望它足够接近。

我有一些代码从数据库表执行SELECT,我知道这将导致大约150万行被选中。 每行中的数据不大 – 每行可能20个字节。 但那仍然是30MB的数据。 每行包含一个客户编号,我需要为每个客户做一些事情。

我的代码看起来像:

SqlConnection conn = new SqlConnection(connString); SqlCommand command = new SqlCommand("SELECT ... my select goes here", conn); using (conn) { conn.Open(); using (SqlDataReader reader = command.ExecuteReader()) { while(reader.Read()) { ... process the customer number here } } } 

所以我只是迭代SELECT返回的所有客户。

我的问题是,这会导致数据库的多次读取,还是只读取一次? 我假设网络缓冲区不足以容纳30MB的数据,那么.NET在这里做什么呢? 每次Read()推进指针时,SELECT的结果是否会让某些地方的SQLDataReader啃掉一行? 还是回到数据库?

我问的原因是代码中的“…处理客户编号”部分可能需要一些时间,因此对于150万客户来说,代码(上面的while循环)将花费很多时间来完成。 当发生这种情况时,我是否需要担心其他人在数据库上阻挡我,或者我知道我已经从数据库中完成了一个SELECT并且我不会再回来了吗?

select将作为“单一,整体事务”执行。 输出的余额缓存在SQL Server中,并在协议确定有可用于接收它的缓冲区时传递到网络。 但是,每次SQL Server都不会返回数据表。 原始SELECT传递给它的数据状态将返回给您的应用程序。 如果指定了(NOLOCK),则不会对数据产生进一步影响。 其他人可以读写; 你不会看到他们的变化。 但是,您还没有完成SQL Server,直到最后一行在您的应用服务器的缓冲区中,数小时后。 每个“我现在有更多空间,请”网络流量,但不会明显超过整个30MB全部遇到的情况。

使用大型结果集和长时间运行的流程,您最好将应用程序编写为批量处理数据,即使基础结构可以支持完整的查询输出。 回答每个批处理查询所需的资源更少。 在失败的情况下,您只需要处理剩余的行; 你不必从头开始。 您的应用程序最终将完成更多的工作,但每个块对环境的破坏性较小。

请求发送一次,而不是每次读取器发送。 然后,结果将根据大小通过几个结果集发送回客户端。

默认结果集是将结果传输到客户端的最有效方式。 从客户端计算机发送到服务器的唯一数据包是包含要执行的语句的原始数据包。 当结果发送回客户端时,SQL Server会将尽可能多的结果集行放入每个数据包中,从而最大限度地减少发送到客户端的数据包数量。

参考http://msdn.microsoft.com/en-us/library/ms187602.aspx

当提交请求以执行时,SQL Server以下列方式将结果集发送回客户端:

  1. SQL Server从客户端接收包含要执行的Transact-SQL语句或批处理的Transact-SQL语句的网络数据包。
  2. SQL Server编译并执行语句或批处理。
  3. SQL Server开始将结果集的行或批处理或存储过程中的多个结果集放入网络数据包并将它们发送到客户端。 SQL Server在每个数据包中放置尽可能多的结果集行。
  4. 包含结果集行的数据包缓存在客户端的网络缓冲区中。 当客户端应用程序提取行时,ODBC驱动程序或OLE DB提供程序从网络缓冲区中提取行并将数据传输到客户端应用程序。 客户端在向前方向上一次检索一行结果。

默认结果集未提供给一个大块中的应用程序。 结果集缓存在客户端的网络缓冲区中。 应用程序一次通过结果集获取一行。 在每次获取时,OLE DB提供程序或ODBC驱动程序将数据从网络缓冲区中的下一行移动到应用程序中的变量。 OLE DB,ODBC和ADO应用程序使用相同的API函数来检索它们用于从游标中获取行的行。 SqlClient托管提供程序使用SqlDataReader类来公开默认结果集。 当MultipleActiveResultSets设置为true时,允许在给定时间打开多个SqlDataReader。

参考: http : //technet.microsoft.com/en-us/library/ms187602(v = sql.105).aspx

首先,我将重定向到SO上的以下问题,其中描述了如何处理锁等:

了解SELECT查询上的SQL Server LOCKS

我的第一个问题是,您将运行此查询多少次。 如果是每日金额,请确保选择用户数量最少的时间。

第二个问题是,你打算怎么处理这些数据? 也许你应该记住,当处理1M +记录时,存储过程会更快,因为它处理数据库上的所有内容并保持低流量。