SQL Server:当过滤器值超出索引直方图范围时使用错误的索引

Posted

技术标签:

【中文标题】SQL Server:当过滤器值超出索引直方图范围时使用错误的索引【英文标题】:SQL Server : wrong index is used when filter value exceeds the index histogram range 【发布时间】:2012-10-04 06:55:56 【问题描述】:

我们有一个非常大的表,每天有 1-2 百万行被添加到表中。

在这个查询中:

SELECT jobid, exitstatus 
FROM jobsData 
WHERE finishtime >= ts '2012-10-04 03:19:26' AND task = 't1_345345_454' 
GROUP BY jobid, exitstatus 

TaskFinishTime 都存在索引。

我们预计将使用 task 索引,因为它的行数要少得多。我们看到的问题是 SQL Server 创建了一个错误的查询执行计划,它使用FinishTime 索引而不是任务,并且查询需要很长时间。

当完成时间值超出FinishTime 索引直方图时会发生这种情况。

统计信息每天/几个小时更新一次,但仍有很多情况下查询是针对最近的值。

问题:在预估的执行计划中我们可以很清楚的看到FinishTime的预估行数在这种情况下是1,所以选择了FinishTime索引。如果没有数据,为什么 SQL Server 假定这是1?有没有办法告诉它使用更合理的东西?

当我们用更早的日期替换日期时,直方图中存在统计信息,估计行数约为 7000

【问题讨论】:

在这种情况下,我只是使用查询提示来强制执行您想要的计划。 查询变化很大,因此很难知道使用哪个提示。我们如何处理对 FinishtTime 索引的预期行的错误估计?为什么引擎猜测它会是 1?他不能取其他桶的平均值吗? @duduamar - 你怎么知道查询变化很大?你和 OP 一起工作吗? 有一些自动工具可以生成这些查询,其中每个查询的时间都不同。我们也有执行查询的痕迹,每个查询都有不同的时间。 【参考方案1】:

您可以使用Plan Guide 来指示优化器为您使用特定的查询计划。这非常适合生成的查询,您无法修改以添加提示。

【讨论】:

这可能会有所帮助 - 谢谢!尽管如此,它仍然需要对我们进行大量更改,因为当前查询将其值作为查询文本的一部分而不是参数。知道为什么在这些情况下估计的行数是“1”吗?将其设置为更接近现有直方图值或例如所有值的平均值 即使您将值指定为标量而不是参数,计划指南仍然可以工作,因为auto-parametrization。

以上是关于SQL Server:当过滤器值超出索引直方图范围时使用错误的索引的主要内容,如果未能解决你的问题,请参考以下文章

从 Excel 导入 SQL Server:将 varchar 数据类型转换为 datetime 数据类型导致值超出范围

将 char 数据类型转换为 datetime 数据类型导致 SQL Server 2005 中的 datetime 值超出范围

转换向量索引超出数组边界 - matlab

线程 1:致命错误:索引超出范围。没有快速从数组中获取值,控制台显示它们不是空数组

NSArrayM objectAtIndex:索引 6 超出范围

sql server中单引号拼接字符串(书写错误会出现错误"浮点值 XXXX 超出了计算机表示范围(8 个字节)。“XX”附近有语法错误。")