【问题标题】:indexes that appear to be redundant with clustered PK似乎与集群 PK 冗余的索引
【发布时间】:2023-03-27 09:33:01
【问题描述】:

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

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])

【问题讨论】:

标签: sql-server


【解决方案1】:

您是正确的,因为聚集索引键已包含在每个非聚集索引中,但与您的示例聚集索引所建议的含义不同。

例如,如果您在 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] 列作为非聚集索引的一部分重复,但是当涉及到非聚集索引时,您肯定要注意您的 SELECTed 字段并知道您是否涵盖了您需要的领域。

【讨论】:

    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多