Sql server 2008 优化器将忽略筛选的索引条件
假设我正在运行一个显示有趣猫图片的网站。我有一个名为Sql server 2008 优化器将忽略筛选的索引条件,sql-server-2008,indexing,filtered-index,Sql Server 2008,Indexing,Filtered Index,假设我正在运行一个显示有趣猫图片的网站。我有一个名为CatPictures的表,其中包含Filename、Awesomeness、和DeletionDate,以及以下索引: create nonclustered index CatsByAwesomeness on CatPictures (Awesomeness) include (Filename) where DeletionDate is null 我的主要问题是: select Filename from CatPictures
CatPictures
的表,其中包含Filename
、Awesomeness
、和DeletionDate
,以及以下索引:
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为null
部分
但是SQLServer不知道这一点;我的查询的执行计划将不使用我的索引:
即使添加索引提示,它仍然会通过查看实际表数据显式检查DeletionDate
:
(此外,还抱怨缺少索引,其中包括DeletionDate
)
我当然可以
include (Filename, DeletionDate)
相反,它将起作用:
但包含该列似乎是一种浪费,因为这样只会占用空间,而不会添加任何新信息
是否有方法使SQL Server意识到筛选条件已在执行检查删除日期的工作?否,当前没有
。它关闭了,因为无法修复。(对于为空的情况,特别是情况)
connect项确实提供了如下所示的解决方法
RichardB CFCU于2011年9月29日上午9:15发布
一种解决方法是包括要筛选的列
例子:
有没有一种方法可以让SQL Server知道筛选条件是正确的
已经在做检查删除日期的工作了吗
没有
过滤索引的目的是解决某些问题,而不是全部问题。随着情况的发展,有朝一日,您可能会看到SQL Server支持您期望的过滤索引功能,但也可能永远看不到它
对于它的工作原理,我有几个很好的理由
它的改进之处:
储藏室。索引仅包含与筛选条件匹配的键
表演。从上面射进来。更少的写入和更少的页面=更快的检索
它没有做什么:
从根本上改变查询引擎
把它们放在一起,考虑到SQL Server是一个高度流水线化、具有多处理器并行能力的beast,我们在处理查询服务时会得到以下行为:
查询优化器选择索引的先决条件:检查筛选的索引是否适用于WHERE子句
查询优化器继续它的正常工作,从统计数据中确定选择性,根据索引是否覆盖等权衡索引->书签查找与聚集/堆扫描
将过滤索引的条件线程化到查询优化器“core”中,我认为这比在步骤1中离开它要大得多
就我个人而言,我尊重SQL Server开发团队,如果它足够简单,他们可能会把它拖进一个不太遥远的冲刺阶段并完成它。然而,what's现在已经达到了它的预期目标,这让我非常高兴。刚刚发现了“功能上的差距”,很遗憾优化器忽略了过滤后的索引。
我想我会尝试使用索引视图,看看这篇文章
表中有多少数据。有时,使用少量数据时,SQL将执行表扫描,因为它更高效。这与运营效率有关。sql保留的统计信息可能正在强制表扫描。您的表包含多少行?SQL server有时更喜欢对选择性较低的小表或索引进行表扫描。@Namphibian我在一个空表和一个500万行的表中看到了同样的情况。而这一次,它不是一个“bug”,而是一个“功能缺口”。SQL server团队什么时候变成了一群政客?那太糟糕了,但我想再权威不过了。谢谢。功能上的差距=无用的特性。@Namphibian只有在你的用例达到这个差距的时候。我已经对使用过滤索引的系统做了一些很好的增强,但这个问题还没有出现。@Aaron这更像是对一个非常有用的特性如何被标记为不是真正的问题的评论。你可能会认为像微软这样的大企业会做一些事情,而不是把它掩盖起来。过滤索引非常好。。。大多数时候。
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)