似乎与群集PK冗余的索引

时间:2014-03-21 20:36:01

标签: sql-server

我正在使用下表在客户端上处理数据库:

CREATE TABLE [Example] (
  [ID]         INT           IDENTITY (1, 1) NOT NULL,
  ....
  [AddressID]  INT NULL,
  [RepName]    VARCHAR(50) NULL,
  ....
  CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED ([ID] ASC)
)

它有以下索引:

CREATE NONCLUSTERED INDEX [IDX_Example_Address]
  ON [example]( [ID] ASC, [AddressId] ASC);
CREATE NONCLUSTERED INDEX [IDX_Example_Rep]
  ON [example]( [ID] ASC, [RepName] ASC);

对我来说,这些似乎与聚集索引是多余的。我无法想象任何这些都有益的情况。如果有人能想出这些有用的情况,请告诉我。

这是另一个例子:

CREATE NONCLUSTERED INDEX [IDX_Example_IsDeleted]
  ON [example]( [IsDeleted] ASC)
  INCLUDE( [ID], [SomeNumber]);

为什么需要包含[ID]?我的理解是聚簇索引键已经存在于每个非聚集索引中,那么他们为什么要这样做呢?我只想包括([SomeNumber])

1 个答案:

答案 0 :(得分:0)

您的正确之处在于聚簇索引键已包含在每个非聚集索引中,但与示例聚簇索引建议的含义不同。

例如,如果您的IDX_Example_Rep示例中有非聚集索引,则运行此查询:

SELECT [RepName], [Id] FROM [Example] WHERE [RepName] = 'some_value';

将使用IDX_Example_Rep索引,但它将是索引扫描(将检查每一行)。这是因为[Id]列被指定为索引中的第一列。

如果索引指定如下:

CREATE NONCLUSTERED INDEX [IDX_Example_Rep] ON [example]([RepName] ASC);

然后,当您运行相同的示例查询时,使用IDX_Example_Rep索引并且操作是索引查找 - 引擎知道完全在IDX_Example_Rep索引中由[RepName]查找记录的位置和,因为SELECT返回的唯一其他字段是[Id]字段,它是聚簇索引的键,因此包含在非聚集索引中,不需要进一步的操作。

如果将SELECT列表扩展为包括[AddressId]字段,那么您将发现引擎仍然对IDX_Example_Rep执行索引查找以查找正确的记录,但之后也进行了密钥查找针对聚集索引获取"其他"字段(本例中的[AddressId])。

所以,不 - 你可能不想重复[Id]列作为非聚集索引的一部分,但是当谈到非聚集索引时,你肯定要注意你的选择字段并知道您是否覆盖了您将需要的字段。