SQL:将主键添加到非唯一索引

时间:2014-10-29 16:39:46

标签: sql sql-server indexing

我们假设一个查询正在过滤两个字段并返回主键值。

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

假设聚簇索引不是PrimaryKey,那么通过添加RowIdentifier(场景A和场景B)可以最好地服务包含QualifierA和QualiferB的非唯一索引。或者仅仅包括它更合适(情景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是既不必要的聚集索引,这是否准确?

2 个答案:

答案 0 :(得分:1)

如果存在CLUSTERED索引,它将自动包含在表的所有索引中。您可以明确地包含它,但这不是必需的。

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

如果你在你的where子句中包含PK,它几乎肯定会使用PK索引来查找该行,因为它保证返回最少的结果,因此包含在你的索引中不会为查找获得任何东西。它还可能使基数引擎出现偏差,并使SQL认为索引比实际更明显。

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

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

无论列是什么列,我都会使用它。这将为您提供性能,确保索引将继续执行而不管CLUSTERED INDEX,并明确指示索引的用途。

答案 1 :(得分:0)

  

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

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

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

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

如果您愿意,可以尝试使用一些测试数据,然后查看查询计划以了解它正在做什么。