我一直在寻找是否有任何简单的方法来获取ADO.NET命令对象的执行时间。
我知道我可以手动执行StopWatch启动和停止。但是想在ADO.NET中有任何简单的方法吗
答案 0 :(得分:8)
有一种方法,但使用SqlConnection
,而不是命令对象。例如:
using (var c = new SqlConnection(connectionString)) {
// important
c.StatisticsEnabled = true;
c.Open();
using (var cmd = new SqlCommand("select * from Error", c)) {
cmd.ExecuteReader().Dispose();
}
var stats = c.RetrieveStatistics();
var firstCommandExecutionTimeInMs = (long) stats["ExecutionTime"];
// reset for next command
c.ResetStatistics();
using (var cmd = new SqlCommand("select * from Code", c))
{
cmd.ExecuteReader().Dispose();
}
stats = c.RetrieveStatistics();
var secondCommandExecutionTimeInMs = (long)stats["ExecutionTime"];
}
Here您可以找到RetrieveStatistics
返回的字典中包含的其他值。
请注意,这些值代表客户端统计信息(基本上是ADO.NET的内部测量值),但似乎您要求模拟Stopwatch
- 我认为这样做了细
答案 1 :(得分:4)
来自answer of @Evk的方法非常有趣和聪明:它正在运行客户端方面,此类统计信息的主要关键之一实际上是NetworkServerTime
,其中3} p>
返回该累计时间(以毫秒为单位) 提供商花了一次等待来自服务器的回复 应用程序已开始使用提供程序并已启用统计信息。
所以它包括从数据库服务器到ADO NET客户端的网络时间。
面向更多数据库服务器的替代方案将运行SET STATISTICS TIME ON
,然后检索InfoMessage
。
委托代码的草稿(我只是写入调试控制台,但您可能希望将其替换为StringBuilder
Append
)
internal static void TrackInfo(object sender, SqlInfoMessageEventArgs e)
{
Debug.WriteLine(e.Message);
foreach (var element in e.Errors) {
Debug.WriteLine(element.ToString());
}
}
和用法
conn.InfoMessage += TrackInfo;
using (var cmd = new SqlCommand(@"SET STATISTICS TIME ON", conn)) {
cmd.ExecuteNonQuery();
}
using (var cmd = new SqlCommand(yourQuery, conn)) {
var RD = cmd.ExecuteReader();
while (RD.Read()) {
// read the columns
}
}
答案 2 :(得分:2)
我建议您转到SQL Server 2016并使用Query Store功能。这将跟踪您提交的每个查询的执行时间和性能随时间的变化。不需要更改您的应用程序。跟踪所有查询,包括在存储过程中执行的查询。跟踪任何应用程序,而不仅仅是您自己的应用程序。适用于所有版本,包括Express,包括Azure SQL DB服务。
如果您在客户端进行跟踪,则必须使用挂钟自行测量时间。我将添加并公开performance counters,然后使用性能计数器基础结构来捕获和存储测量值。
作为一个方面,仅仅跟踪发送到SQL Server的批处理的执行时间会产生非常粗糙的性能信息,并且很少可操作。阅读How to analyse SQL Server performance。