有时,通常几乎不需要运行时间的查询突然开始需要2秒的时间来运行。(查询为select count(*) from calendars
,返回数字10)。只有当通过应用程序运行查询时才会发生这种情况,而不是直接在数据库服务器上运行查询时。当我们重新启动应用程序服务器软件(Tomcat)时,性能突然恢复正常。通常情况下,我会责怪网络,但重新启动应用程序服务器会让它突然表现得更快,这对我来说毫无意义。
我的怀疑落在了连接池上,但我尝试了各种不同的设置和多个不同的连接池,仍然得到了相同的结果。我目前正在使用HikariCP。
有人知道是什么原因导致了这样的事情吗?或者我该如何诊断这个问题?
您使用存储过程还是特别查询?关于在运行查询时获得不同执行的原因,比如说在management studio中与在应用程序中使用存储过程相比,缓存执行计划可能效率低下,因为参数嗅探可能会生成这样的执行计划。你可以在这里阅读更多关于它的信息,你可以尝试很多解决方案(比如用局部变量代替参数)。如果重新启动整个计算机(SQL Server也在其上运行),这可以解释为什么在重新启动后一开始会得到快速查询,因为重新启动后会清理执行计划。
事实证明,我们有一个无赖的过程,它一次获取了64个到数据库的连接,并将所有这些连接用于紧张而低效的工作。我们能够使用jstack对此进行诊断。当我们注意到系统速度减慢了一吨时,我们运行了jstack,它向我们展示了应用程序的工作原理。我们看到64个堆栈跟踪都在同一个流氓进程中,我们有了答案!