0

我有这个查询:

SELECT
    COUNT(*) AS 'RedactedCount'
    ,s.Redacted1
    ,s.[Redacted2]
    ,s.[Redacted3] AS 'Redacted3'
FROM RedactedTable1 s
    LEFT OUTER JOIN RedactedTable2 g ON s.Redacted5= g.Redacted5
WHERE g.Redacted6= 31013 AND s.DateTime >= '2013-03-02 00:00:00'
GROUP BY s.Redacted1,s.Redacted2, s.Redacted3

其中有一个非常奇怪的行为。此查询需要整整 1 分 30 秒才能完成。如果我将日期更改为 2013-04-02 00:00:00(今天我正在写这篇文章),它几乎是即时的,这是预期的行为。

但是,如果我将日期更改为 2013-02-02(2 个月的时间跨度而不是 1),则查询只需 20 秒。

有没有人遇到过这个问题?我对结果完全震惊。这也将是我正在处理的 Web 应用程序的重要 SQL 请求。

  • Microsoft SQL Server 管理工作室 11.0.3128.0
  • Microsoft 数据访问组件 (MDAC) 6.1.7601.17514
  • 微软 MSXML 3.0 6.0
  • 微软 Internet Explorer 9.0.8112.16421
  • 微软 .NET 框架4.0.30319.296
  • 系统开发6.1.7601

注意:数据库设计得很糟糕,并且绝对不包含索引。是的,这很糟糕。不幸的是,这是一个商业软件,我无权更改数据库模型。但是,我不认为我的问题是由此引起的。

PS:对不起,如果我的查询被大量编辑,因为我在严格的 NDA 上。我试图让它尽可能可读。

谢谢 !

4

3 回答 3

1

首先,在外连接外侧的表上放置谓词条件是没有意义的。执行此操作后,最终结果集中在该表中没有匹配的所有行都将被删除,从而有效地使整个查询表现得好像它是一个内部连接。

如果您希望连接包括表 RedactedTable2 中没有匹配行的行,则 RedactedTable2.Redacted6 上的条件应该是连接条件的一部分。

 SELECT COUNT(*) AS 'RedactedCount',
     s.Redacted1, s.[Redacted2],
     s.[Redacted3] AS 'Redacted3'
 FROM RedactedTable1 s
      LEFT JOIN RedactedTable2 g 
          ON g.Redacted5= s.Redacted5
             And g.Redacted6= 31013 
 WHERE s.DateTime >= '2013-03-02 00:00:00'
 GROUP BY s.Redacted1,s.Redacted2, s.Redacted3

至于为什么会出现性能差异,我怀疑您的问题是由表中的数据引起的,导致查询处理器在一种情况下使用与另一种情况不同的执行计划。这很容易发生。如果优化器“猜测”它需要使用一个查询执行计划检查超过一定百分比的数据行,基于关于表中数据值分布的数据库统计信息),那么它将切换到不同的计划。在打开 ShowPlan 选项的情况下运行这两个查询,看看有什么不同。

于 2013-04-02T14:41:32.223 回答
1

除了 Charles 建议的内容之外,您还可以要求数据库管理员(假设您有)UPDATE STATISTICS至少在 RedactedTable1 和 RedactedTable2 上运行。 UPDATE STATISTICS要求您对ALTER表/视图具有权限,所以我怀疑您是否有权运行它。但你可能会要求它完成。像您所描述的问题通常是由过时的统计数据引起的。

于 2013-04-02T15:54:17.563 回答
0

Aaron Bertrand 在评论中得到了答案。

这个问题是由 MSSQL 进行的参数嗅探引起的。

声明和使用虚拟变量可防止 MSSQL 使用过去的优化错误地优化查询。

以下链接帮助我了解了参数嗅探http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

于 2013-04-03T13:27:25.730 回答