【发布时间】:2017-03-20 14:17:01
【问题描述】:
我们有一个应用程序,它给人的印象是数据库响应不佳。数据库和应用服务器都没有负载过重,但应用程序花费大量时间通过 ExecuteReader 进行查询。
我们正在测量两件事:SQL Server Profiler 中的批处理和语句持续时间,以及调用 ExecuteReader 和处理它之间的时间。数据的消耗是“微不足道的”,即。只需将数据读入字典列表即可。
Profiler 记录的持续时间通常远小于应用程序记录的持续时间。这些查询只返回几行(通常是一行),因此使用结果集所花费的时间应该很小。 但是我们已经看到应用程序将 150 毫秒查询(由分析器记录)记录为超过 1700 毫秒的实例。
环境:
- 这不是我们的基础设施。
- 它是实时的,因此我们无法附加分析器/调试器。
- 应用服务器至少是虚拟化的。数据库是一个集群。
- SQL Server 2008R2 和 Windows Server 2008R2。
一个明显的罪魁祸首是网络延迟,但ping 表明从应用程序到数据库服务器的延迟始终小于 1 毫秒。
连接被重复用于多个查询,因此 Open() 时间开销应该已经单独考虑。我预计这可以排除 ExecuteReader 期间的身份验证延迟,但也许我错了?
我们还应该调查哪些其他事情? ExecuteReader 可能会等待哪些其他事情?
【问题讨论】:
-
“连接被重复用于多个查询”——这让我担心——如何或为什么连接被重复使用?
-
在同一个 NHibernate 会话中的多个查询,特别是。
-
线程之间永远不会共享连接,并且我们关闭了 MARS(查询只会连续运行)。应用程序的某些部分依赖于临时表,这些临时表会在连接关闭时丢失,因此有时需要在多个查询之间保留连接。不过,任何连接都很少能存活超过几秒钟。
-
@Damien_The_Unbeliever 它应该只是一个打开的
SqlConnection,然后使用该连接执行多个SqlCommands,而不在每个查询之间关闭它。这很好,因为它与通过 SSMS 中的GO进行多批次相同。
标签: c# sql-server ado.net sqldatareader