为什么我的索引查找可以估计正确的行数而排序运算符不能呢?


11

我有一个查询,该查询在谓词上使用函数,如下所示:

commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)

我在commentType上有一个经过筛选的索引,该索引具有40K行,当我运行查询时,Index Seek的估计行数非常准确(大约11K),但是对于下一步(sort运算符),它完全忽略了统计信息,仅估算过滤索引中的总行数。

为什么会这样呢?我知道有关可保留性的基础知识,并且为了安全起见,我已经进行了测试,以实际日期(2014-01-01)替换dateadd和voila ...排序开始正确地猜测行数...

为什么会发生这种情况,我该如何解决?我无法通过固定日期...


DATEADD(month,datediff(month,0,getdate()) - 13,0)对我来说没有意义。您打算怎么做?可以改进/简化吗?
Daniel Hutmacher '16

2
@Daniel这是13个月前的月初。
亚伦·贝特朗

1
另外,请编辑您的问题以反映您所使用的SQL Server(?)的版本。为此使用标签。
Daniel Hutmacher '16

您可以尝试DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))看看是否有区别吗?
Daniel Hutmacher '16

如果您在上具有未过滤的索引(commentType, commentDate),那么该索引的性能会更好吗?只是过滤后的索引有时可能会误报计划中不同点的估计。通过在过滤后的索引中报告总数,估计值似乎不合时宜,但实际上是计划显示有误。
罗布·法利

Answers:


9

我相信您的估算是错误的,因为估算器错误会交换两个DATEDIFF参数。我在这里谈论这个:

一种解决方法是不使用DATEDIFF(2008+)来计算13个月前的第一天:

DATEADD(MONTH, -13, DATEADD(DAY, 1-DATEPART(DAY,GETDATE()), CONVERT(DATE, GETDATE()));

我不积极,将解决的估计(我没有与过滤索引测试,我不知道是什么的排序究竟是干什么或为什么它没有计划和/或查询的其余部分不同的估计)。

Microsoft建议的修复程序是使用TF 4199,但是我不确定这是您在这里需要执行的操作:

另一种选择是确保所使用的任何版本的SQL Server都在绝对最新的SP / CU上,因为他们声称此问题已在下面的知识库文章中得到修复(尽管这仍然需要使用TF 4199除非您的年龄在2014年或以上):

可以使用以下内部版本获得此修复程序:

  • 2005 SP3 CU 15(> = 9.00.4325和<= 9.00.4999)
  • 2005 SP4 CU 2(> = 9.00.5259)
  • 2008 SP1 CU 13(> = 10.00.2816.00 AND <= 10.00.3999)
  • 2008 SP2 CU 3(> = 10.00.4279.00 AND <= 10.00.5499)
  • 通过扩展2008 SP3和SP4(> = 10.00.5500)
  • 2008 R2 CU 7(10.50.1777.0)
  • 2008 R2 SP1 CU 3(> = 10.50.2769.0 AND <= 10.50.3999)
  • 通过扩展2008 R2 SP2和SP3(> = 10.50.4000)
  • 通过扩展2012、2014、2016(> = 11.0)

(下一次,请SELECT @@VERSION在您的问题中包括结果。)

我将注意到,知识库文章说DATEDIFF可能低估了行数,这与您的方案中发生的情况相反。这并不意味着这些修补程序不适用于您;我认为知识库文章的措词不准确,因为估算值可以根据数据和所要查找的范围进行任意一种选择。

我在上面的博客文章中确认,这种交换不会在2014年及以后发生。为了安全起见,我可能只是从谓词中删除DATEDIFF并使用其他方法来计算范围的开始。我不建议过度使用4199或使用动态SQL来防止错误交换。


谢谢您的帮助 !我尝试了您的建议,计划改变了。这是以前的样子s16.postimg.org/t5j6o1yed/fix_wrong.png这是我更改您的datediff后的样子postimg.org/image/5f725rj83 我将阅读您提供给我的所有网址。干杯。
MrKudz '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.