代码之家  ›  专栏  ›  技术社区  ›  Dustin Laine

SQL重叠索引和多列索引

  •  0
  • Dustin Laine  · 技术社区  · 15 年前

    我正在尝试优化一些存储过程,并对索引有一个问题。我使用了调优顾问,他们为同一个表推荐了两个索引。问题是,一个索引针对一列,另一个索引针对多个列,其中包含第一列中的同一列。我的问题是为什么,有什么区别?

    CREATE NONCLUSTERED INDEX [_dta_index_Table1_5_2079723603__K23_K17_K13_K12_K2_K10_K22_K14_K19_K20_K9_K11_5_6_7_15_18]
    ON [dbo].[Table1]  (    
        [EfctvEndDate] ASC,     
        [StuLangCodeKey] ASC,
        [StuBirCntryCodeKey] ASC,
        [StuBirStOrProvncCodeKey] ASC,
        [StuKey] ASC, 
        [GndrCodeKey] ASC,
        [EfctvStartDate] ASC,
        [StuHspncEnctyIndctr] ASC,
        [StuEnctyMsngIndctr] ASC,
        [StuRaceMsngIndctr] ASC,
        [StuBirDate] ASC,   
        [StuBirCityName] ASC 
    ) INCLUDE (
        [StuFstNameLgl],
        [StuLastOrSrnmLgl], 
        [StuMdlNameLgl],
        [StuIneligSnorImgrntIndctr],
        [StuExpctdGrdtngClYear]
    ) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) 
    ON [PRIMARY] go
    
    CREATE NONCLUSTERED INDEX [_dta_index_Table1_5_2079723603__K23]
    ON [dbo].[Table1]  (
        [EfctvEndDate] ASC 
    )WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF)     
    ON [PRIMARY]
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Mitch Wheat    15 年前

    如果像上面的例子一样,单列是在多列索引中定义的第一列:它并不总是正确的,或者查询工作负载随时间而变化。如果多列索引是有益的,并且正在使用中,您可以删除单列索引。但是,分析并检查索引使用情况报告。

    如果不是,则适用于不同的查询。我注意到DTA喜欢做的一件事是创建一个索引,它本质上是整个表的副本,特别是在ORM发出查询工作负载的情况下。

    与本例及所有其他示例一样,您必须进行概要分析,以确定与“正常”查询工作负载相关的任何索引的有效性。

        2
  •  2
  •   mjv    15 年前

    “独立”efctvenddate索引,同时 功能上 在另一个索引中可用的索引将更小,因此效率更高(关于所需的读取次数、缓存的能力、保持在缓存中的能力等)。

    当然,这在很大程度上取决于使用模式等。但是,是的,总的来说,拥有多个明显冗余的索引是一种敏感的方法是非常合理的。

    索引“重复”的缺点主要是(而且可能是为了更大到更小的影响):

    • 在基础表上插入/更新/删除查询,会导致维护额外索引的性能开销。
    • 缓存使用竞争
    • [非常轻微]生成查询计划的时间更长。
    • 存储开销(通常是无问题的;但会增加备份时间…)。

    因此,必须估计select查询的改进性能是否能够抵消上面列出的缺点,而select查询可能会从额外的索引中受益。数据库性能优化通常是一个个案练习…