SQL Server 2008 - 奇怪的慢查询

Posted

技术标签:

【中文标题】SQL Server 2008 - 奇怪的慢查询【英文标题】:SQL Server 2008 - Weird slow query 【发布时间】:2011-05-19 14:17:08 【问题描述】:

我在数据库中有一张大表(数百万条记录,大小约为 500GB)。

在这张表中,我有很多列,其中有一个名为FinishTime 的日期字段。 该字段上有一个索引。

现在问题来了:

当我使用条件 FinishTime >= <now - 10 hours> 运行一个简单的选择查询时 - 查询需要很长时间才能完成。

当我使用条件FinishTime >= <now - 11 hours> 运行一个简单的选择查询时 - 查询立即完成。

奇怪的是,第二个查询的输出应该包含第一个查询的所有输出,甚至更多。

更多信息:我正在使用 MS JDBC 驱动程序通过 JAVA 应用程序运行这些查询。我正在使用 PreparedStatement。

运行这两个查询的代码是相同的。

有什么想法吗?

谢谢

编辑:更多信息和更正: 我还有一个相关字段 - JobId,整数,它也有一个索引。 问题似乎发生在这些查询上(由于 PAGEIOLATCH_SH,我在管理工作室看到卡住的查询):

卡住的查询:

select * from jobsData (with readuncommitted) where ([FinishTime >= ts '2011-05-19 09:23:00') AND ([JobId]=5)

立即完成的查询:

select * from jobsData (with readuncommitted) where ([FinishTime >= ts '2011-05-19 04:23:00') AND ([JobId]=5)

【问题讨论】:

在 SQL Server Mgmt Studio 中运行这两个查询时会发生同样的事情吗?? 您的统计数据是最新的吗? 请包括完整的查询和相关表的架构。 不,奇怪的是,当在 Mgmt Studion 上运行时,两个查询都会立即结束。是的,我的统计信息已更新,并且我已包含查询。 请发布每个查询的执行计划以及表架构。 【参考方案1】:

作为一个准备好的语句,它可能优化了传入的第一个参数的查询(我猜是 11 小时减法)

这可以通过执行带有强制重新编译查询计划的提示的查询来测试。

见 - http://msdn.microsoft.com/en-us/library/ms181714.aspx

这不是一个很好的解决方案,但如果这提高了性能,您知道它与此相关,您可以查看添加查询提示,或者如果只有有限范围的值将被传递给每个变体的语句。

编辑 - 从您上面的评论中说他们都立即在管理工作室中运行,这似乎加强了我的感觉。

查询计划缓存由 sqlserver 而不是 java 应用程序完成,

 connection.prepareStatement(sqlstring);

将您的语句传递给 sqlserver,将变量位置通知它,并让它在第一次运行时根据它生成可重用的查询计划。我怀疑(但如果不搜索文档就无法确定)调用它会强制构建一个新的查询计划,因为这会抵消它的大部分好处。

尝试将查询构建为字符串并执行它,而不是对查询进行参数化。

【讨论】:

我为每个查询调用 Connection.prepareStatement,我没有对两个查询使用相同的语句。这会改变你的答案吗?

以上是关于SQL Server 2008 - 奇怪的慢查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中的常量函数(使用函数的慢视图)

SQL Server:存储过程变得非常慢,原始 SQL 查询仍然非常快

SQL Server 2008 - 性能慢查询

如何查找MySQL中查询慢的SQL语句

MySQL删除千万级数据量导致的慢查询优化

如何动态开启mysql的慢查询日志记录