我有一张非常大的桌子,里面有很多行和很多列(我知道这很糟糕,但让我们把它放在一边)。
具体来说,我有两列 - FinishTime, JobId
。第一个是行的结束时间,第二个是它的id(不唯一,但几乎是唯一的 - 只有少数记录存在相同的id)。
我有关于完成时间的jobid和索引的索引。
我们一直在插入行,大部分按完成时间排序。我们还定期更新每个指数的统计数据。
现在问题:
当我使用过滤器jobid==<some id> AND finishtime > <now minus 1 hour>
运行查询时 - 此查询需要花费大量时间,并且在显示估计的执行计划时,我看到该计划将覆盖finishtime
索引,即使超过jobid
指数应该会好很多。查看索引统计信息时,我看到服务器“认为”过去一小时内的作业数为1,因为我们没有更新此索引的统计信息。
当我使用过滤器jobid==<some id> AND finishtime > <now minus 100 days>
运行查询时 - 这很有用,因为SQL Server知道要检查正确的索引 - 作业ID索引。
所以基本上我的问题是为什么如果我们不一直更新索引统计信息(这很耗时),服务器会假设过去最后一个桶的记录数是1?
非常感谢
答案 0 :(得分:1)
您可以使用DBCC SHOW_STATISTICS获取统计信息所包含的直方图,例如
DBCC SHOW_STATISTICS ( mytablename , myindexname )
对于基于日期的记录,查询总是容易出现错误的统计信息。运行此应该表明直方图中的最后一个桶几乎没有任何记录[在今天之前/之后]。但是,在其他条件相同的情况下,如果两个索引都是没有包含列的单列索引,SQL Server仍然应该优先选择job_id
索引到finishtime
索引。这是因为job_id(int)比finishtime(datetime)更快地查找。
注意:如果您的finishtime
覆盖了查询,这将极大地影响查询优化器选择它,因为它消除了书签查找操作。
要解决这个问题,要么