优化器忽略过滤的索引条件

Posted

技术标签:

【中文标题】优化器忽略过滤的索引条件【英文标题】:Filtered index condition is ignored by optimizer 【发布时间】:2012-06-05 12:20:08 【问题描述】:

假设我正在运行一个显示有趣猫图片的网站。我有一个名为CatPictures 的表,其中包含FilenameAwesomenessDeletionDate 列,以及以下索引:

create nonclustered index CatsByAwesomeness
on CatPictures (Awesomeness) 
include (Filename)
where DeletionDate is null

我的主要问题是:

select Filename from CatPictures where DeletionDate is null and Awesomeness > 10

作为一个人,我知道上面的索引就是 SQL Server 所需要的全部,因为索引过滤条件已经确保了DeletionDate is null 部分。

但是 SQL Server 不知道这一点;我的查询的执行计划不会使用我的索引:

即使添加索引提示,它仍然会通过查看实际表数据来显式检查DeletionDate

(此外还抱怨缺少包含DeletionDate 的索引)。

当然可以

include (Filename, DeletionDate)

相反,它会起作用:

但是包含该列似乎是一种浪费,因为这只会占用空间而没有添加任何新信息。

有没有办法让 SQL Server 知道过滤条件已经在执行检查 DeletionDate 的工作?

【问题讨论】:

表中有多少数据。有时,对于少量数据,SQL 会进行表扫描,因为它更有效。这与运营效率有关。 sql 保留的统计信息可能会强制进行表扫描。 你的表有多少行? SQL Server 有时更喜欢对选择性较低的小表或索引进行表扫描。 @Namphibian 我在空表和 500 万行的表中看到了同样的情况。 【参考方案1】:

不,目前没有。

See this connect item。它因无法修复而关闭。 (或 this one 专门针对 IS NULL 案例)

connect 项确实提供了如下所示的解决方法。

RichardB CFCU 于 2011 年 9 月 29 日上午 9:15 发布

解决方法是INCLUDE 正在过滤的列。

示例:

CREATE NONCLUSTERED INDEX [idx_FilteredKey1] ON [dbo].[TABLE] 
(
    [TABLE_ID] ASC,
    [TABLE_ID2] ASC
)
INCLUDE ( [REMOVAL_TIMESTAMP]) --explicitly include the column here
WHERE ([REMOVAL_TIMESTAMP] IS NULL)

【讨论】:

还有这个,它不是“错误”,而是“功能差距”。 SQL Server 团队什么时候变成了一群政客? connect.microsoft.com/SQLServer/feedback/details/454744/… 这太糟糕了,但我想没有比这更权威的了。谢谢。 功能上的差距 = 无用的功能。 @Namphibian 仅当您的用例达到差距时。在未出现此问题的情况下,我使用过滤索引对系统进行了一些重大改进。 @Aaron 更多的是关于如何将非常有用的功能标记为不是真正问题的评论。你会期望像微软这样的大企业会做一些事情而不是掩盖它。过滤索引很棒......大多数时候。【参考方案2】:

有没有办法让 SQL Server 知道过滤条件是 已经完成检查删除日期的工作了吗?

没有。

过滤索引旨在解决某些问题,而不是全部。随着事情的发展,总有一天,您可能会看到 SQL Server 支持您期望的过滤索引功能,但也有可能您永远看不到它。

我可以看到它的工作原理有几个很好的理由。

改进的地方:

    存储。索引只包含匹配过滤条件的键 性能。从上面的一个嘘声。更少的写入和更少的页面 = 更快的检索

它没有做什么:

    彻底改变查询引擎

将它们放在一起,考虑到 SQL Server 是一个高度流水线、多处理器并行能力的野兽,我们在处理查询服务时会得到以下行为:

    查询优化器选择索引的前提条件:检查过滤索引是否适用于 WHERE 子句。 查询优化器继续正常工作,从统计数据中确定选择性,权衡索引->书签查找与集群/堆扫描,具体取决于索引是否覆盖等

我怀疑将过滤索引的条件线程化到查询优化器“核心”中,这比将其留在第 1 步要大得多。

就个人而言,我尊重 SQL Server 开发团队,如果它足够简单,他们可能会将其拉入一个不远的冲刺并完成它。但是,目前的情况已经达到了预期,让我很高兴。

【讨论】:

【参考方案3】:

刚刚发现“功能上的差距”,过滤索引被优化器忽略真的很遗憾。 我想我会尝试使用索引视图,看看这篇文章

http://www.sqlperformance.com/2013/04/t-sql-queries/optimizer-limitations-with-filtered-indexes

【讨论】:

以上是关于优化器忽略过滤的索引条件的主要内容,如果未能解决你的问题,请参考以下文章

为啥查询优化器完全忽略索引视图索引?

为啥优化器不使用我的唯一过滤索引?

索引的使用

Hive入门Hive优化

ElasticSearch中文索引优化问题

Oracle查询速度优化问题