真是奇怪的DataReader性能问题

我有一个SQL Server数据库,我正在使用ADO.NET ExecuteReader来获取一个datareader。 我的存储过程返回大约35,000条记录。

对ExecuteReader的调用大约需要3秒钟才能返回datareader。

我正在使用与此非常相似的代码来获取我的项目。

using(var conn = new SqlConnection(MySQLHelper.ConnectionString)) { conn.Open(); var sqlCommand = SqlHelper.CreateCommand(conn, "spGetItems"); using (var dr = sqlCommand.ExecuteReader()) { while(dr.read){ var item = new Item{ID = dr.GetInt32(0), ItemName = dr.GetString(1)}; items.Add(item); } } } 

大多数读取花费0毫秒。 然而,间歇性地我得到一个大约5.5秒(5000+毫秒)的读取。 我查看了数据,并没有发现任何exception。 我认为开始考虑记录这么长时间的记录的频率。

这很有趣。 虽然不完全一致,但它们很接近。 需要很长时间才能加载的记录如下……

记录#s:29,26,26,27,27,29,30,28,27,27,30,30,26,27

因此看起来26到30个记录会在0到几毫秒内读取,然后需要5秒,然后接下来的26到30个记录将再次按预期读取。

我在这里完全失败了。 我可以发布更多代码,但没有多少。 这是非常简单的代码。

编辑我的字段都不是varchar(max),甚至是close。 我最大的字段是数字(28,12)。

修改我的存储过程后,我不再有问题。 我首先将其修改为选择TOP 100,然后将其提升至Top 1000,然后是10,000,然后是100,000。 我从来没有遇到过这些问题。 然后我移到了TOP,现在我没有遇到我之前的问题。

SqlDataReader缓冲发送到客户端的结果。 有关详细信息,请参阅MSDN上的此页 :

当结果发送回客户端时,SQL Server会将尽可能多的结果集行放入每个数据包中,从而最大限度地减少发送到客户端的数据包数量。

我怀疑你每包得到26-30条记录。 当您遍历记录时,加载新记录时会出现延迟。

我有类似的问题。 答案是使用nvarchar(max)转换所有文本字段,然后在类似的时间段内将.NET ExecuteReader返回到MS Studio中的sproc的Exec。 请注意,sproc不包含事务,但.NET调用包含在事务中。

你读的桌子结构是什么? 你不是第二列使用nvarchar(max)类型吗?

没有程序运行存储过程需要多长时间? 我怀疑它需要花费很长时间才能运行,并且你会看到因为缓冲这种奇怪的行为,正如其他人指出的那样。