多个索引或覆盖索引以及包含



我有一个大型过程,它对一个包含约5000万条记录的表执行大量更新和选择,查询计划显示缺少索引,这将有所帮助:

缺少索引(影响89.4367):CREATE NONCLUSTERED Index缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLA])INCLUDE([用户ID]、[价格])

缺少索引(影响90.7279):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLB])INCLUDE([用户ID]、[价格])

缺少索引(影响90.4069):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别],[季度][COLC])INCLUDE([用户ID],[价格])

缺少索引(影响90.6373):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLD])INCLUDE([用户ID]、[价格])

缺少索引(影响88.774):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLE])INCLUDE([用户ID]、[价格])

缺少索引(影响89.9133):CREATE NONCLUSTERED Index[lt;的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLF])INCLUDE([用户ID]、[价格])

缺少索引(影响90.1297):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLF])INCLUDE([用户ID]、[价格])

缺少索引(影响76.6554):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLG])INCLUDE([用户ID]、[价格])

缺少索引(影响90.9105):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLH])INCLUDE([用户ID]、[价格])

缺少索引(影响84.1814):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLI])INCLUDE([用户ID]、[价格])

缺少索引(影响89.3511):CREATE NONCLUSTERED Index[lt;的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLJ])INCLUDE([用户ID]、[价格])

缺少索引(影响90.3087):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable](【类别】、【季度】、【COLK】)INCLUDE(【用户ID】、【价格】)

缺少索引(影响90.6367):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLL])INCLUDE([用户ID]、[价格])

缺少索引(影响75.6598):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLM])INCLUDE([用户ID]、[价格])

缺少索引(影响82.8915):CREATE NONCLUSTERED Index[lt;的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLN])INCLUDE([用户ID]、[价格])

缺少索引(影响88.2316):CREATE NONCLUSTERED Index[lt;的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLO])INCLUDE([用户ID]、[价格])

缺少索引(影响81.9138):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLP])INCLUDE([用户ID]、[价格])

缺少索引(影响80.1902):CREATE NONCLUSTERED Index[<的名称缺少索引,sysname,>]ON[dbo]。[myTable]([类别]、[季度]、[COLP])INCLUDE([用户ID]、[价格])

我的问题是我是否应该:

  1. 创建它建议的所有索引

  2. 创建包含所有列的覆盖索引,例如

CREATE NONCLUSTERED INDEX indexA 
ON [dbo].[myTable] ([Category], [Quarter], [COLA], [COLB], [COLC], [COLD], [COLE], [COLF], 
[COLG], [COLH], [COLI], [COLJ], [COLK], [COLL], [COLM], [COLN], [COLO], [COLP])  
INCLUDE ([UserId],[Price])  
  1. 使用includes中的所有列创建索引,例如
CREATE NONCLUSTERED INDEX indexB 
ON [dbo].[myTable] ([Category], [Quarter])   
INCLUDE ([COLA], [COLB], [COLC], [COLD], [COLE], [COLF], [COLG], [COLH], [COLI],
[COLJ], [COLK], [COLL], [COLM], [COLN], [COLO], [COLP], [UserId], [Price])
  1. 其他组合

我知道可能没有确切的答案,但你会推荐哪一个,为什么?

添加索引的主要问题是它们会减慢数据更新操作(插入、删除、更新),因为索引也需要更新。

虽然这个答案是基于意见的,但imo有一个主要考虑因素——表多久更新一次(例如,新的插入/更新/删除)?

  • 如果没有更新(或者只有手动更新),那么根据需要创建尽可能多的索引-这可以对引用表等执行。但这不是引用表imo
  • 或者,如果它是一个有数据负载的数据仓库表,那么每天都要完成索引重建,这也是可行的
  • 另一方面,如果它有很多更新,例如,一次加载一个事务,或者以小批量加载,那么更多的索引将降低这些更新的性能
    • 由于这个原因,我通常非常反对在事务表上有许多非聚集索引(以及太宽的索引)

注意,对于索引,主索引中只能有一定数量的字节(尽管包含字段可能更长)。因此,对所有字段进行索引可能是不可行的。此外,将所有这些字段作为索引的一部分可能没有帮助——当它需要(比如)ColB时,数据已经按ColA排序了——因此它无论如何都需要再次读取整个索引。

就我个人而言,我建议从[Category],[Quarter],[COLA]的索引开始,然后包括所有其他字段。如果其他列的使用频率更高,则可以将ColA替换为其他任何列。它提供

  • 是ColA部分的一个很好的索引,因为它提供了所需的所有信息(覆盖索引),并且排序正确,并且
  • 其他部分的覆盖指数

它仍然需要进行索引扫描,但值得一试。看看这是否能将查询速度提高到可接受的水平。

不过,请注意,如果您已经有

  • [Category],[Quarter]
  • 其他字段中的数据很少(例如,表中没有varchar(2000)字段,但此字段未使用

。。。那么非聚集索引可能没有多大帮助。

同样,根据您对该表的其他操作,如果[Category],[Quarter]上的聚集索引是而不是,那么您可能希望这样做。但请注意,如果其他任何东西使用此表,则可能会导致性能不佳。

相关内容

最新更新