为了在创建新索引时提高效率,如果已经有一个具有相同索引键的索引,但它只需要额外的包含列,那么创建第二个索引(再次使用相同的键)是否更好不同的包含列?或者查询引擎(不重新创建索引)重新创建索引并将包含列添加到原始包含列集会更有效吗?
如果只是将包含列添加到现有索引,那么附加包含列的顺序是否重要?
是否存在创建第二个索引更有意义的场景,复制索引键,但使用一组不同的包含列?
我试图在下面的代码中简化这个问题。
CREATE NONCLUSTERED INDEX [IX_Index_A] ON [dbo].[Table]
([Col1] ASC)
INCLUDE ([Col2])
CREATE NONCLUSTERED INDEX [IX_Index_B] ON [dbo].[Table]
([Col1] ASC)
INCLUDE ([Col3],[Col4])
或者
DROP INDEX [IX_Index_A] ON [dbo].[Table]
CREATE NONCLUSTERED INDEX [IX_Index_A] ON [dbo].[Table]
([Col1] ASC)
INCLUDE ([Col2],[Col3],[Col4])
包含的字段顺序无关紧要,因为不涉及排序——这些字段在索引的每一行的叶级可用。
像第二个示例那样合并它们并没有真正的缺点,除了该索引上的页面密度(每行数读取更多页面,因为每行存储了更多数据)。
但是,有一些可衡量的优势 - 对于更新/插入,
Col1
您只需要更新一个索引而不是两个,并且通过不在col1
两个单独的索引中保留重复的键条目,您将节省大量空间。我能想到的唯一有两个更窄索引有意义的场景是,如果其中一个索引是专门为关键任务过程或视图设计的。如果您的索引仅包含某个以高频率运行的查询所需的内容,那么尽可能简化它是有意义的。
我会说在这种情况下合并您的索引,因为每个插入、删除和适当的更新都需要索引维护 * n 索引。此外,如果您拥有企业版,则可以使用 WITH (DROP_EXISTING = ON, ONLINE = ON) 来减少中断。