我正在使用下表在客户端上处理数据库:
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])
答案 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]列作为非聚集索引的一部分,但是当谈到非聚集索引时,你肯定要注意你的选择字段并知道您是否覆盖了您将需要的字段。