过滤索引包含哪些列?

时间:2012-10-01 10:01:08

标签: sql-server sql-server-2008 database-design

假设有一个名为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)

哪个INDEX更正确?

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

OR

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

OR

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

示例和问题2)

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

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

1 个答案:

答案 0 :(得分:2)

首先,消除误解:

  

假设只有20%的行像这样......显而易见   过滤索引

不,这根本不明显。我认为指数有时需要大约1%的选择性。通常,阈值报价为5%。有一篇关于它的文章,但我不记得在哪里。在Google上搜索。

关于你的3个变种

  

在T1上创建非压缩索引IX_Attrib1(Attrib1,Attrib1Date)   Attrib1 = 1

由于SQL Server实现了过滤索引,因此索引键中需要Attrib1。但是,将它置于第1位并不会使它具有很强的选择性。

  

在T1上创建非压缩索引IX_Attrib1(Attrib1Date,Attrib1)   Attrib1 = 1

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

  

在T1上创建非压缩索引IX_Attrib1(Attrib1Date)   Attrib1 = 1

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

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

    失败
      

    在T1上创建非压缩索引IX_Attrib2(Attrib2)   在哪里Attrib2 = 1

    是的,如果只是为了创建索引,你会这样做,并且列的列表是针对超出filtered index applicability检查的常规查询优化器/引擎。