0

假设有一个名为 T1 的表

CREATE TABLE T1
(
  GID INT NOT NULL,
  Attrib1 BIT NOT NULL,
  Attrib1Date DATE NOT NULL,
  Attrib2 BIT NOT NULL,
  CONSTRAINT PK_T1 PRIMARY KEY (GID)
)

现在,我正在为查询创建索引,其中只有 Attrib1 等于 1 或 Attrib2 等于 1 的行是有趣的。假设只有 20% 的行是这样的。

请不要担心 Attrib1 与 Attribe2 的关联——它们仅针对两个单独的示例给出。

使用过滤索引很明显——我的意思是:带有 WHERE 子句的 INDEX-es。但问题是要包括哪些列?

示例查询:

SELECT * FROM T1 WHERE Attrib1 = 1 ORDER BY Attrib1Date
SELECT * FROM T1 WHERE Attrib2 = 1

示例和问题 1)

哪个索引更正确?

CREATE NONCLUSTERED INDEX IX_Attrib1
ON T1 (Attrib1, Attrib1Date)
WHERE Attrib1 = 1

或者

CREATE NONCLUSTERED INDEX IX_Attrib1
ON T1 (Attrib1Date, Attrib1)
WHERE Attrib1 = 1

或者

CREATE NONCLUSTERED INDEX IX_Attrib1
ON T1 (Attrib1Date)
WHERE Attrib1 = 1

示例和问题 2)

构建仅包含过滤列的过滤索引是否正确,例如:

CREATE NONCLUSTERED INDEX IX_Attrib2
ON T1 (Attrib2)
WHERE Attrib2 = 1
4

1 回答 1

2

首先,消除误解:

假设只有 20% 的行是这样的……使用过滤索引很明显

不,一点也不明显。我认为有时需要考虑该指数的选择性约为 1%。通常,阈值引用为 5%。有一篇关于它的文章,但我不记得在哪里。在谷歌上搜索它。

在您的 3 个变体上

在 T1(Attrib1,Attrib1Date)上创建非聚集索引 IX_Attrib1,其中 Attrib1 = 1

由于 SQL Server 实现了筛选索引,因此索引键中需要 Attrib1。但是,将其放在位置 1 并不会使其具有很高的选择性。

在 T1 (Attrib1Date, Attrib1) WHERE Attrib1 = 1 上创建非聚集索引 IX_Attrib1

这个比上面的更具选择性,并且会更可取。前置条件用于检查过滤索引的适用性,但之后,常规查询引擎将接管,它将执行正常的选择性检查等。

在 T1 (Attrib1Date) 上创建非聚集索引 IX_Attrib1,其中 Attrib1 = 1

由于上述原因,这个不太理想,因为处理过程如下:

  1. 查询包含WHERE Attrib1 = 1-> 可以考虑此索引(具有其他潜力)
  2. Attrib1Date 是否足够有选择性?
  3. 索引包含 (Attrib1Date + record-pointer) => 这些可以为请求提供服务,包括WHERE Attrib1 = 1条件

它在#3失败

在 T1 (Attrib2) WHERE Attrib2 = 1 上创建非聚集索引 IX_Attrib2

是的,如果只是为了创建索引,您会这样做,并且包含该列是为了接管检查之外的常规查询优化器/引擎filtered index applicability

于 2012-10-01T10:18:50.607 回答