SqlCommand.ExecuteReader持续时间小于SQL事件探查器批处理持续时间

时间:2013-03-06 13:09:28

标签: .net sql-server duration executereader

如SQL Profiler中所见,对SqlCommand.ExecuteReader的调用如何比SQL批处理本身花费更少的时间?

我在控制台应用程序中运行了以下简单代码,该应用程序调用了SqlCommand.ExecuteReader,我使用的是Stopwatch对象:

var swQueryTime = new Stopwatch();

        var conn = new SqlConnection("Data Source=.;Initial Catalog=master;Trusted_Connection=True;");
        conn.Open();
        string sql = string.Format(@"select * from sys.dm_os_memory_clerks; select * from sys.dm_os_performance_counters ");

        for (int i = 0; i < 10; i++)
        {                
            var comm = new SqlCommand(sql, conn);
            swQueryTime.Restart();

            var dr = comm.ExecuteReader();

            swQueryTime.Stop();

            Console.WriteLine("ElapsedMilliseconds: {0}", swQueryTime.ElapsedMilliseconds);

            dr.Close();
            comm = null;
        }

平均而言,SQL批处理持续时间是.Net端报告的4倍。

我检查过profiler是专门报告的毫秒数。

我没有使用SqlCommand.ExecuteReader的异步版本。

Profiler持续时间不是我使用Profiler开始和结束时间读取和验证的多个线程/核心的所有时间总和。

赞赏的想法。

1 个答案:

答案 0 :(得分:2)

因为您只有批次的开始时间。如果你消费数据,那么时间可能会排成一行:

using(var dr = comm.ExecuteReader()) {
    do {
        while(dr.Read()) {}
    } while (dr.NextResult());
}

顺便提一下,还有一些SET选项可以改变某些查询的性能 - 不确定应该在这里应用,但它会显着影响具有计算+持久值的表:如果{{1创建列时,值与设置不兼容,需要重新运行每行的计算。对于计算的+持久+索引列,如果要对该列进行过滤,则尤其值得注意 - 它必须执行表扫描(或类似)而不是索引扫描/索引搜索。