【问题标题】:SQL Server randomly 200x slower than normal for simple query对于简单查询,SQL Server 随机比正常慢 200 倍
【发布时间】:2014-09-16 19:29:03
【问题描述】:

有时,通常几乎不需要时间运行的查询突然开始需要 2 秒才能运行。 (查询为select count(*) from calendars,返回数字10)。这仅在通过我们的应用程序运行查询时发生,而不是在直接对数据库服务器运行查询时发生。当我们重新启动应用服务器软件 (Tomcat) 时,性能突然恢复正常。通常我会责怪网络,但重新启动应用程序服务器会使它突然变得更快对我来说没有任何意义。

我的怀疑落在了连接池上,但我尝试了各种不同的设置和多个不同的连接池,结果还是一样。我目前正在使用 HikariCP。

有谁知道是什么原因导致了这种情况,或者我可以如何诊断问题?

【问题讨论】:

    标签: sql-server jdbc hikaricp


    【解决方案1】:

    您使用存储过程还是临时查询?在运行查询时获得不同执行的原因让我们说在管理工作室与在应用程序中使用存储过程可能是低效的缓存执行计划,这可能是由于参数嗅探而生成的。您可以阅读更多关于它的信息here,并且您可以尝试多种解决方案(例如用局部变量替换参数)。如果您重新启动整台计算机(并且 SQL Server 也在其上运行),那么这可以解释为什么您在重新启动后一开始就获得快速查询 - 因为执行计划在重新启动后被清除。

    【讨论】:

    • 我们使用临时查询。此外,当我们重新启动时,我们不会触及数据库服务器,我们只是重新启动 Tomcat,这是我们的应用服务器软件。我们不会重新启动任何物理机器。我正在运行的查询是 select count(*) from calendars 该查询只返回数字 10。
    • 我不知道长期保持的连接是否存在问题,但您可以尝试将连接池中的maxLifetime 属性设置为大约 10 分钟。此外,连接数会影响 SQL 服务器本身,因此请尝试将连接池限制为一到两打连接。
    • 我们实际上已经尝试将maxLifetime 设置为 10 分钟,但这并没有帮助。我们在具有 32 个处理核心和超线程的数据库服务器上运行。我们尝试了 68、130 和 5000 的连接池大小,都出现了同样的问题。我们要尝试的下一件事是看看使用 JMX 在池中发生了什么。我们将在 9 月底有结果。 (我们无法运行 JConsole,因为这是一个在国防部安全位置运行的生产箱)。
    【解决方案2】:

    事实证明,我们有一个恶意进程,它一次抓取 64 个与数据库的连接,并将所有这些连接用于紧张而低效的工作。我们能够使用jstack 对此进行诊断。当我们注意到系统速度变慢了很多时,我们运行了 jstack,它向我们展示了应用程序正在做什么。我们在同一个流氓进程中看到了 64 个堆栈跟踪,我们有了答案!

    【讨论】:

    • 很高兴您找到了原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 2013-01-25
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多