【问题标题】:SQL Server 2008 - Weird slow querySQL Server 2008 - 奇怪的慢查询
【发布时间】: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 上运行时,两个查询都会立即结束。是的,我的统计信息已更新,并且我已包含查询。
  • 请发布每个查询的执行计划以及表架构。

标签: sql-server-2008


【解决方案1】:

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

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

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

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

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

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

 connection.prepareStatement(sqlstring);

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

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

【讨论】:

  • 我为每个查询调用 Connection.prepareStatement,我没有对两个查询使用相同的语句。这会改变你的答案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多