2014-10-29 74 views
0

假设查询正在过滤两个字段并返回主键值。SQL:将主键添加到非唯一索引

SELECT RowIdentifier 
FROM Table 
WHERE QualifierA = 'exampleA' AND QualifierB = 'exampleB' 

假设聚簇索引不是的PrimaryKey将包含QualifierA和QualiferB通过加入RowIdentifier(情况A &情形B)来提供最好的服务的非唯一索引。或者仅仅包括它会更恰当(情景C)?

场景A:非唯一,非聚集

CREATE NONCLUSTERED INDEX IX_Table_QualifierA 
ON [dbo].[Table] ([QualifierA],[QualifierB],[RowIdentifier]) 

场景B:独特的,非聚集

CREATE UNIQUE NONCLUSTERED INDEX IX_Table_QualifierA 
ON [dbo].[Table] ([QualifierA],[QualifierB],[RowIdentifier]) 

方案C:

CREATE NONCLUSTERED INDEX IX_Table_QualifierA 
ON [dbo].[Table] ([QualifierA],[QualifierB]) 
INCLUDE ([RowIdentifier]) 

最后我假设如果PrimaryKey是非必要的聚集索引,这是否准确?

+0

为了澄清,您是否在讨论如何合并包含这三个字段的非聚类非唯一索引? – 2014-10-29 17:16:17

+1

@ScottTeibert我想知道什么更合适?包含所有三个字段的非聚集唯一索引,或仅包含两个字段(QualifierA和QualifierB)但包含PrimaryKey的非聚集非唯一索引。 – 2014-10-29 17:31:20

+1

@FrumRoll - 所有3个场景都覆盖了索引,但是由于RowIdentifier只会包含在叶级别,所以场景C的索引会更小。你是正确的,如果主键被聚集,那么QualifierA和QualifierB上的索引将被覆盖。 – 2014-11-11 17:23:36

回答

1

如果有一个CLUSTERED索引,它会自动包含在该表的所有索引中。你可以明确地包含它,但它不是必需的。

UNIQUE索引只是强制唯一性。 PK应该已经有了这个限制。您无需在每个索引中重新执行它。

如果你在你的where子句中包含PK,它几乎肯定会使用PK索引来查找该行,因为它保证返回最少的结果,因此包括在你的索引中对于查找没有任何收获。它也可能会歪曲基数引擎,并使SQL认为索引比实际更明显。

基于上述原因,我会选择选项C

CREATE NONCLUSTERED INDEX IX_Table_QualifierA 
ON [dbo].[Table] ([QualifierA],[QualifierB]) 
INCLUDE ([RowIdentifier]) 

我想无论是什么样聚集列中使用此。这会给你的表现,确保索引将继续执行,无论集群索引如何,并明确索引的用途。

0

我在想什么更合适?包含所有三个字段的非群集唯一索引,或仅包含两个字段(QualifierA & QualifierB)但包含PrimaryKey的非群集非唯一索引。

还有第三种选择。包含所有三个字段的非聚集,非唯一索引。

制作索引时,索引中的字段会复制到内存中的其他位置,以便服务器可以轻松地在这些字段后面进行操作。如果您在索引中只有QualiferA和Qualifier B,它会在该索引中找到符合条件的行,然后返回主表以获取RowIdentifier。相反,包括所有三个以提高性能。

请记住,请确保您将RowIdentifier之前的QualifierA和QualifierB放入您的索引中。列的顺序决定了数据的排序方式。

如果您愿意,可以试试一下测试数据,然后查看查询计划,看看它在做什么。

+0

我已经提供了额外的说明,看起来你是在方案B中提倡方案A.为什么UNIQUE约束会引入不必要的开销?同样以A或B的哪种方式优于C? – 2014-10-29 19:27:38