我根据Index向导为不同场景建议的方式创建了这两个索引。 我想知道它们是相同还是不同?
索引(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)
答案 0 :(得分:4)
问题是,您想要优化哪些查询?
这两个指标非常不同。第一个索引对于这样的查询非常有用:
SELECT CaseId
FROM Rec.RecoveryDate
WHERE RecoveryTypeKey = 5
AND CurrentFlag = 1 -- or whatever
第一个索引WHERE子句中的列。 SQL Server将能够搜索指定的RecoveryDateTypeKey和CurrentFlag。由于CaseId在索引叶节点中是INCLUDEd,因此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,因此它可能会进行索引扫描。
答案 1 :(得分:2)
差异基本上意味着如果使用两列进行搜索,索引1可能比索引2快得多 索引2将优于一列的正常索引,因为如果您需要结果中的其他列,则索引2已经具有该值,因此不需要使用实际表进行查找。
答案 2 :(得分:0)
索引存储相同的信息(Recovery表中每行1行,包含caseid,RecoveryDateTypeKey,CurrentFlag列),但是以不同的顺序组织,因此可以用于不同的查询。
第一个索引可以处理where子句,例如
WHERE RecoveryDateTypeKey = @p1 --Prefix matching!
和
WHERE RecoveryDateTypeKey = @p1 AND CurrentFlag = @p2
第二个索引只处理
WHERE CurrentFlag = @p2
如果CurrentFlag是一个低基数列,如位或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.
每个筛选的索引仅包含符合条件的值,因此组合它们的大小与未筛选的索引相同。