高使用率下两类SQL索引是否应合并?案例分析与疑问
索引合并决策分析:两组示例对比
示例1:Orders表索引
原索引定义:
CREATE INDEX [ix_Orders_1] ON [dbo].[Orders] ([cancelled], [approved], [denied], [saved]) INCLUDE ([total], [subTotal], [tax]) CREATE INDEX [ix_Orders_2] ON [dbo].[Orders] ([cancelled], [isQuote]) INCLUDE ([dateStamp], [userId])
决策:保持分开
- 两个索引的键列仅第一列
cancelled相同,第二列分别指向approved和isQuote,对应完全不同的查询过滤逻辑 - 已知两个索引使用率都很高,说明各自服务的查询场景差异明显,合并后会导致索引键列冗余,既增加数据更新时的索引维护成本,也会让查询时的索引扫描效率下降,因此应该保留为两个独立索引。
示例2:Products表索引
原索引定义:
CREATE INDEX [ix_Products_1] ON [dbo].[Products] ([itemNumber]) INCLUDE ([altItemNumber], [description]) CREATE INDEX [ix_Products_2] ON [dbo].[Products] ([itemNumber], [showPrice]) INCLUDE ([level_1], [level_2], [level_3], [level_4])
决策:可以合并,且不影响性能
你提出的合并方案是可行的,合并后的索引定义:
CREATE INDEX [ix_Products_3] ON [dbo].[Products] ([itemNumber], [showPrice]) INCLUDE ([altItemNumber], [description], [level_1], [level_2], [level_3], [level_4])
理由如下:
- 原两个索引的键列是前缀包含关系:
ix_Products_1的键列itemNumber是ix_Products_2键列的前缀,合并后的索引依然能被依赖ix_Products_1的查询高效利用——查询可以通过首列itemNumber快速定位数据,所需的INCLUDE字段也全部覆盖 - 依赖
ix_Products_2的查询完全匹配合并后的索引键列和INCLUDE列,性能不受影响 - 合并后减少了一个索引的维护开销(插入、更新、删除数据时的索引更新操作),同时不会牺牲查询性能,因此推荐合并。
内容的提问来源于stack exchange,提问作者Joe Defill
相关产品推荐
相关产品推荐

