1

我根据索引向导针对不同场景的建议创建了这两个索引。我想知道它们是相同的还是不同的?

索引(1):

CREATE NONClustered Index [IX_Rec_RecoveryDate_RecoveryDateTypeKey_CaseId] 
ON [Rec].[RecoveryDate] ([RecoveryDateTypeKey], [CurrentFlag])
INCLUDE (CaseId)

索引(2):

CREATE NONClustered Index [IX_Rec_RecoveryDate_currentFlag] 
ON [Rec].[RecoveryDate] ([CurrentFlag])
INCLUDE (CaseId, RecoveryDateTypekey)
4

3 回答 3

4

问题是,您要优化哪些查询?

这两个指标非常不同。第一个索引非常适合这样的查询:

SELECT CaseId 
FROM Rec.RecoveryDate
WHERE RecoveryTypeKey = 5
AND CurrentFlag = 1 -- or whatever

第一个索引 WHERE 子句中的列。SQL Server 将能够搜索指定的 RecoveryDateTypeKey 和 CurrentFlag。由于 CaseId 包含在索引叶节点中,SQL Server 不必重新连接到表来获取它。

使用相同的查询,第二个索引的行为会有所不同。如果幸运的话,SQL Server 会搜索 CurrentFlag 为 1 的所有记录。然后,它会遍历这些叶节点,寻找匹配的 RecoveryTypeKey。另一方面,如果有很多 CurrentFlag 为 1 的记录,SQL Server 可能会选择执行索引扫描。

再说一次,如果你想优化这样的查询:

SELECT CaseId, RecoveryTypeKey
FROM Rec.RecoveryDate
WHERE CurrentFlag = 1

第一个索引没有用,因为 CurrentFlag 是索引中的第二列。SQL Server 将无法搜索 CurrentFlag = 1,因此它可能会进行索引扫描。

于 2012-12-04T22:23:22.360 回答
2

他们是不同的。索引 1 索引两列,索引 2 索引一列但在节点中包含两列。

区别基本上意味着如果您使用两列进行搜索,索引 1 可能比索引 2 快得多。
索引 2 会比一列的普通索引更好,因为如果您需要结果中的另一列,索引 2已经具有该值,因此不需要使用实际表进行查找。

于 2012-12-04T22:11:00.497 回答
0

索引存储相同的信息(Recovery 表中每行 1 行,列 caseid、RecoveryDateTypeKey、CurrentFlag),但以不同的顺序组织,因此可用于不同的查询。

第一个索引可以处理 where 子句,例如

WHERE RecoveryDateTypeKey = @p1 --Prefix matching!

WHERE RecoveryDateTypeKey = @p1 AND CurrentFlag = @p2

第二个索引只处理

WHERE CurrentFlag = @p2

如果 CurrentFlag 是低基数列,例如 bit 或 char(1) (Y/N),那么我建议使用过滤索引。

CREATE INDEX IX_REC_Yes_fltr on Recovery (RecoveryDateTypeKey) WHERE (CurrentFlag = 'Y')
INCLUDE (CaseId) --Assumes that CurrentFlag = 'Y' is the most used value

--Maybe even a second one.
CREATE INDEX IX_REC_No_fltr on Recovery (RecoveryDateTypeKey) WHERE (CurrentFlag = 'N')
INCLUDE (CaseId) --Maybe handle CurrentFlag = 'N' as well.

每个过滤索引只包含符合条件的值,因此组合起来它们的大小与未过滤索引的大小相同。

于 2012-12-05T05:42:47.407 回答