2

与 SQL Profiler 中看到的 SQL 批处理本身相比,对 SqlCommand.ExecuteReader 的调用如何花费更少的时间来完成?

我在调用 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 倍。

我检查了探查器是专门报告毫秒。

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

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

想法赞赏。

4

1 回答 1

2

因为您只有从批次开始的时间。如果你也使用数据,时间可能会排成一行:

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

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

于 2013-03-06T13:18:11.177 回答