假设我正在运行一个显示有趣猫图片的网站。我有一个名为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 is null
部分。
然而,SQL Server不知道这一点;我的查询的执行计划不会使用我的索引:
即使添加索引提示,它仍会通过查看实际的表数据显式检查DeletionDate
:
(并且还抱怨缺少包含DeletionDate
的索引。)
当然我可以
include (Filename, DeletionDate)
相反,它会起作用:
但是包含该列似乎是浪费,因为这只会占用空间而不添加任何新信息。
有没有办法让SQL Server知道过滤条件已经在检查DeletionDate
?
答案 0 :(得分:18)
不,不是。
See this connect item。它是关闭的,因为无法修复。 (或IS NULL
具体说明this one)
连接项确实提供了如下所示的解决方法。
RichardB CFCU发表于29/09/2011 at 9:15 AM
解决方法是
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)
答案 1 :(得分:2)
有没有办法让SQL Server知道过滤条件是 已经完成了检查DeletionDate的工作?
没有
过滤的索引旨在解决某些问题,而非ALL。事情在发展,有一天,您可能会看到SQL Server支持您对过滤索引所期望的功能,但您也可能永远看不到它。
有几个很好的理由我可以看到它的工作原理。
改进之处:
不做的事情:
将它们放在一起,考虑到SQL Server是一个高度流水线,多处理器并行能力的野兽,我们在处理查询服务时会遇到以下行为:
将过滤后的索引的条件线程化到查询优化器“核心”中,我怀疑这将比在第1步中留下更大的工作。
就个人而言,我尊重SQL Server开发团队,如果它很容易,他们可能会把它拉到一个不太遥远的冲刺中并完成它。然而,目前的目标已经实现了它的目的,让我感到非常高兴。
答案 2 :(得分:1)
刚刚发现“功能上的差距”,优化器忽略了过滤的索引,真的很难过。 我想我会尝试使用索引视图,看一下这篇文章
http://www.sqlperformance.com/2013/04/t-sql-queries/optimizer-limitations-with-filtered-indexes