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

问题描述

如果一个表有 'id'(主键)列作为它的聚集索引,在 Microsoft sqlServer 的任何其他非聚集索引中添加 'id' 列作为包含列有什么好处吗?

例如:-表'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'

解决方法

您问题的答案基本上是否定的,没有任何好处。

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

如果基表是,则索引中的每一行都将包含一个指向rid(行标识符)的指针,这是 SQL Server 用来唯一标识的每一行。

当表定义有聚集索引时,每个非聚集索引将自动包含聚集索引列作为基表中行的

您可以在执行计划中看到这一点,其中使用了非聚集索引并且 SQL Server 必须从基表中检索其他列;如果表是,则是RID 查找,如果表有聚集索引,则是键查找

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

因此,当涉及非聚集索引时,是否指定聚集索引列并不重要 - 您可以,并且这样做没有害处,但它/它们总是被包含在内。

> ,

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

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...