DataReader的性能问题确实很奇怪

时间:2011-11-16 20:16:21

标签: c# sql-server ado.net

我有一个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+毫秒)的读取。我查看了这些数据,并没有发现任何异常。我认为开始考虑记录这么长时间的记录的频率。

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

记录#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,现在我没有遇到我早先的问题。

4 个答案:

答案 0 :(得分:3)

SqlDataReader缓冲发送给客户端的结果。见this page on MSDN for details

  

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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