如果 table 具有 'id' 列作为聚集索引,那么将 'id' 列添加为任何其他非聚集索引中的包含列是否有任何好处

If a table has 'id' column as it's clustered index, is there any benefit in adding 'id' column as an included column in any other non-clustered index

如果 table 具有 'id'(主键)列作为其聚集索引,将 'id' 列添加为任何其他非索引中的包含列是否有任何好处? Microsoft SQLServer 中的聚簇索引?

例如:- Table 'xyz'

id 名字 状态 日期
1 abc 活跃 2021-06-23
CREATE NONCLUSTERED INDEX [NonClusteredIndex_status_Date]
                ON [xyz]
                    (   
                        [status] ASC,
                        [date] ASC
                    )
                INCLUDE
                    (   [id],
                        [name]
                    ) 

并且此非聚集索引针对类似于大型数据集上的波纹管的查询。在实际情况下,可能还会有一些其他查询。

select * from xyz where status='active' and date > '2021-06-20'

此答案假定您计划运行以下查询:

SELECT * FROM xyz WHERE status = 'active' AND date > '2021-06-20';

如果您只在 (status, date) 上创建了一个非聚集索引,那么它会覆盖 WHERE 子句,但 不会 SELECT条款。这意味着 SQL 服务器可能会选择使用索引来查找查询中的匹配记录。但是当它开始评估 SELECT 子句时,它将被迫返回聚簇索引以查找未包含在索引中的列的值,而不是 id 聚簇索引列(在这种情况下包括 name 列)。这样做会降低性能,SQL 根据您的数据,服务器甚至可能选择不使用索引,因为它没有完全覆盖查询。

为了缓解这种情况,您可以在问题中定义索引,在叶节点中包含 name 值。请注意 id 将默认包含在索引中,因此我们不需要显式 INCLUDE 它。按照这种方法,索引本身被认为完全 覆盖 查询,这意味着 SQL 服务器可以将索引用于整个查询计划。在许多情况下,这可以带来快速的性能。

你的问题的答案基本上是No,没有任何好处。

当您在 table 上创建非聚集索引时,索引中的每一行都需要能够指向基础 table 中的行。

如果基table是一个,索引中的每一行都将包含一个指向rid的指针(行标识符),这是 SQL 服务器用来唯一标识每一行的内容。

当 table 定义了聚簇索引时,每个非聚簇索引将自动包含聚簇索引列作为 keys 到行基地 table.

您可以在执行计划中看到这一点,其中使用了非聚集索引并且 SQL 服务器必须从基础检索额外的列 table;如果 table 是一个 ,它将是一个 RID 查找 ,如果 table 有一个聚集索引它将是一个键查找

此外,如果聚集索引不是唯一,SQL服务器添加自己的uniquifier值以确保唯一性,这也包含在非聚集索引中。

因此,对于非聚集索引,是否指定聚集索引列并不重要 - 您可以,这样做没有任何坏处,但 it/they 总是包括在内。