Tia*_*ago 11 index sql-server statistics
我有一个在谓词上使用函数的查询,如下所示:
commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)
Run Code Online (Sandbox Code Playgroud)
我在 commentType 上有一个过滤索引,它有 40K 行,当我运行查询时,Index Seek 的估计行数非常准确(大约 11K),但对于下一步(排序运算符),它完全忽略了统计信息和只是估计过滤索引中的总行数。
为什么会这样?我知道有关sargability的基础知识,并且我只是为了理智而进行了测试,将 dateadd 替换为实际日期(2014-01-01),瞧......排序开始正确猜测行数......
为什么会发生这种情况,我该如何解决?我不能通过一个固定的日期...
我相信你的估计是错误的,因为一个估计器错误交换了两个 DATEDIFF 参数。我在这里谈这个:
一种解决方法是在不使用 DATEDIFF (2008+) 的情况下计算 13 个月前的第一天:
DATEADD(MONTH, -13, DATEADD(DAY, 1-DATEPART(DAY,GETDATE()), CONVERT(DATE, GETDATE()));
Run Code Online (Sandbox Code Playgroud)
我不肯定会解决估计问题(我没有用过滤索引进行测试,我不确定排序实际上在做什么,或者为什么它在没有计划和/或查询的其余部分的情况下有不同的估计)。
Microsoft 建议的修复程序是使用 TF 4199,但我不太确定您需要在这里做什么:
另一种选择是确保您使用的是绝对最新的 SP/CU,适用于您使用的任何版本的 SQL Server,因为他们声称它已在以下知识库文章中修复(尽管这仍然需要使用 TF 4199除非你在 2014 年或更好):
可以通过以下构建获得修复:
(下次,请SELECT @@VERSION在您的问题中包括结果。)
我会注意到知识库文章说 DATEDIFF 可以低估行数,这与您的场景中发生的情况相反。这并不意味着这些修复不适用于您;我认为知识库文章的措辞不准确,因为根据数据和您正在查看的范围,估计值可能会有所不同。
我上面的博客文章证实,交换不再发生在 2014 年及以后。为安全起见,我可能只是从您的谓词中删除 DATEDIFF 并使用不同的方法来计算您的范围的开始。我不建议过度使用 4199 或使用动态 SQL 来防止错误交换。