当“包含”列不同时,为同一列创建索引的正确方法

时间:2014-05-06 17:58:29

标签: sql-server sql-server-2008 indexing

我们说我有2个存储过程和1个表。

  • 表名:Table_A
  • 程序名称:proc1proc2

当我使用执行计划运行proc1时,它建议我为Table_A(不是主键)列创建tblID的索引,并建议包含{{ 1}}和column_A

并且column_B建议再次为proc2列创建Table_A的索引,但这次它建议包括tblIDcolumn_B(它为此程序建议column_C而不是column_C

所以我的问题是,如果我创建了一个包含所有建议列的索引,如:

column_A

这会导致任何性能问题吗?

收集CREATE NONCLUSTERED INDEX indexTest ON [dbo].[Table_A] ([tblID]) INCLUDE ([column_A],[column_B],[column_C]) 列是否有任何不利之处?

或者我应该创建2个不同的索引:

INCLUDE

更新:我想在这个问题上再补充一点。

如果我对主要字段做同样的事情:

我的意思是,

proc-1建议在CREATE NONCLUSTERED INDEX indexTest_1 ON [dbo].[Table_A] ([tblID]) INCLUDE ([column_A],[column_B]) CREATE NONCLUSTERED INDEX indexTest_2 ON [dbo].[Table_A] ([tblID]) INCLUDE ([column_B],[column_C]) 字段上创建索引。 proc-2建议在tblIDtblID上创建索引。

如果我把它们收集起来:

column_A

这是否会导致性能问题?或者我应该为建议的主要字段创建2个单独的索引吗?

2 个答案:

答案 0 :(得分:7)

绝对创建包含所有三列的一个索引!

您拥有的索引越少越好 - 索引维护是一个成本因素 - 更多索引需要更多维护。

所包含的列仅包含在索引的叶级中 - 对性能的影响非常小。

更新:如果您在(tblID, column_A)上有一个索引,那么您可以将其用于在其{中仅使用 tblID的查询{1}}子句,或者您可以将它用于在WHERE子句中同时使用这两列的查询。

HOWEVER:对于在WHERE子句中仅使用 column_A的查询,此索引无用。如果给定查询使用索引中指定的最左侧的列,则复合索引(由多列组成的索引)才有用。

因此,在您的情况下,一个查询似乎表示WHERE,而另一个查询需要tblID - 所以是的,在这种情况下,我认为单个索引 (tblID, column_A)适用于两种查询。

答案 1 :(得分:3)

听起来你正在看missing index dmvs。这里有几件事需要实现。 dmvs实际上是在告诉您特定查询或特定索引可能有帮助的类似组。

从这个意义上说,你是正确的结合索引。这是正确的想法。

但是,还要记住索引有成本,并且这个dmv的工作不是权衡这个成本。你绝对不想自动创建一个索引来涵盖每个推荐。您还想检查这些索引:一旦包含A,B和C列,您是否将整个表(或几乎如此)保留在索引中?您是否可以通过更改主键以匹配此索引来获得更好的结果?小心评估最后一部分,因为更改主键可能会将先前的密钥保留为更重要的缺失索引。