我有这个问题:
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秒才能完成。我应该将de date更改为2013-04-02 00:00:00(今天我正在写这篇文章),它几乎是即时的,这是预期的行为。
但如果我将日期更改为2013-02-02(2个月的时间跨度而不是1),则查询只需20秒。
有没有人遇到过这个问题?我对结果感到震惊。它也将是我正在处理的Web应用程序的重要SQL请求。
注意:数据库设计很差,并且绝对没有索引。是的,这很糟糕。不幸的是,这是一个商业软件,我没有权利对数据库模型进行更改。但是,我不认为我的问题是由此造成的。
P.S。:对不起,如果我的查询被大量编辑,因为我是严格的NDA。我尽量让它变得可读。
谢谢!
答案 0 :(得分: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选项的情况下运行两个查询,并查看差异是什么。
答案 1 :(得分:1)
除了Charles建议您可以要求数据库管理员(假设您有)在至少RedactedTable1和RedactedTable2上运行UPDATE STATISTICS
。 UPDATE STATISTICS
要求您对表/视图拥有ALTER
权限,因此我怀疑您是否有权运行它。但你可能会要求它完成。您所描述的问题通常是由过时的统计数据引起的。
答案 2 :(得分:0)
Aaron Bertrand在评论中得到答案。
此问题是由MSSQL执行的参数嗅探引起的。
声明和使用虚拟变量可防止MSSQL使用过去的优化错误地优化查询。
以下链接帮助我了解参数嗅探http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx