20

假设我正在运行一个显示有趣猫图片的网站。我有一个名为CatPictures、 和 列的表FilenameAwesomeness以及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

4

3 回答 3

18

不,目前没有。

请参阅此连接项。它因无法修复而关闭。(或者这个专门针对这种IS NULL情况)

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

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)
于 2012-06-05T12:26:36.720 回答
2

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

不。

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

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

它改进了什么:

  1. 贮存。索引只包含匹配过滤条件的键
  2. 表现。从上面的一个嘘声。更少的写入和更少的页面 = 更快的检索

它不做什么:

  1. 彻底改变查询引擎

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

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

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

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

于 2012-10-01T11:41:48.463 回答
1

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

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

于 2013-05-27T10:36:15.640 回答