哪些因素会影响ExecuteReader的持续时间?

时间:2017-03-20 14:17:01

标签: c# sql-server ado.net sqldatareader

我们有一个应用程序,它给人的每一印象都是因为数据库响应不佳而受到瓶颈。数据库和应用程序服务器都没有大量加载,但是应用程序花费了大量时间通过ExecuteReader进行查询。

我们正在测量两件事:SQL Server Profiler中的批处理和语句持续时间,以及调用ExecuteReader和处理它之间的时间。消费数据是“微不足道的”即。只需将数据读入字典列表即可。

Profiler记录的持续时间通常远低于应用程序记录的持续时间。这些查询只返回几行(通常是一行),因此使用结果集所需的时间应该很小。 但是我们已经看到应用程序记录了超过1700ms的150ms查询(由分析器记录)的实例。

环境:

  • 这不是我们的基础设施。
  • 它已存在,因此我们无法附加探查器/调试器。
  • 应用程序服务器至少是虚拟化的。数据库是一个集群。
  • SQL Server 2008R2和Windows Server 2008R2。

显而易见的罪魁祸首是网络延迟,但ping表示从应用程序到数据库服务器的延迟始终小于1毫秒。

连接被重用于多个查询,因此Open() - 时间开销应该已经单独计算。我会期待这可以排除ExecuteReader期间的身份验证延迟,但也许我错了吗?

我们应该调查哪些其他内容? ExecuteReader可能会等待哪些其他内容?

1 个答案:

答案 0 :(得分:2)

  

我们已经看到150ms查询的实例(由分析器记录)被应用程序记录为超过1700ms。

确切地说,该应用程序如何记录持续时间?使用StopWatch,还是那种性质的东西?或者来自SqlConnection.RetrieveStatistics()报告的客户统计信息?

您是否检查过运行查询的请求的等待类型字段?在sys.dm_exec_requests DMV中,有四个字段包含可能在此处有用的信息:wait_typewait_timelast_wait_typewait_resource。即使查询在内部快速将结果返回给SQL Server,它仍然需要用一个线程将这些结果发送回调用者。

另外,有些事情只是为了帮助缩小可能性:

  • 关闭连接池。在ConnectionString中,使用Pooling=false;。这仍然允许在同一连接上进行多次查询(因此不会干扰临时表的使用)。是的,它会略微增加总体时间,因为它需要对每个连接进行身份验证,但它会排除某些问题,并且会停止"。

  • 如果可能(尚未执行此操作),请在CommandBehavior.SequentialAccess的调用中指定ExecuteReader()。这可以防止在调用SqlDataReader.Read()时整行的本地缓存,这有助于当你有大量的字符串和/或二进制值,甚至没有检索,或者如果有很多列,你只是抓住一个少。