如何将非聚集索引变成覆盖索引

Posted

技术标签:

【中文标题】如何将非聚集索引变成覆盖索引【英文标题】:how to turn non-clustered Index into covering indexs 【发布时间】:2019-11-01 21:57:07 【问题描述】:

我搜索了覆盖索引,发现:

“覆盖索引是一种特殊类型的复合索引,所有列都存在于索引中。”

我了解主要目的是让非聚集索引不查找聚集索引,而对于 SQL Server,我们可以在创建索引时使用 'INCLUDE' 列,因此 SQL Server 在叶级添加它们指数。所以不需要通过cluster-index查找。

但是我们有一个客户表(CustID,FirstName,City),它在 CustID 上有一个聚集索引。

如果我们在 FirstName 列上创建一个非聚集索引(称为 IX_FIRSTNAME),并将该列作为有效负载包含在索引的叶节点中并查询为:

select FirstName from Customers where FirstName Like 'T*';

那么在这种情况下,就不需要通过clustered Index查找了,那么IX_FIRSTNAME可以认为是覆盖索引吗?

或者它必须满足所有列的要求? 并且我们需要为所有三列创建一个非聚集索引来作为覆盖索引?

【问题讨论】:

为什么Customers 表是heap? @Mazhar ,我已编辑我的帖子以在 CustID 上添加聚集索引 【参考方案1】:

这里有两个概念:

聚集索引与非聚集索引 覆盖索引

覆盖索引可以满足查询中的 where 子句。由于您可能会针对您的数据运行多个查询,因此给定索引可能会“覆盖”一个查询,但不会覆盖另一个查询。

在您的示例中,IX_FIRSTNAME 是查询的覆盖索引

select FirstName from Customers where FirstName Like 'T*';,

但不适用于查询

select FirstName from Customers where FirstName Like 'T*' and City Like 'London';.

许多性能优化归结为“了解您的查询,尤其是 where 子句,并设计覆盖索引”。为每个可能的列组合创建索引是个坏主意,因为索引确实有其自身的性能成本。

第二个概念是“聚集”与“非聚集”索引。这更多是一个物理问题——使用聚集索引,数据按索引的顺序存储在磁盘上。这非常适合在表的主键上创建索引(如果您的主键是递增整数)。在您的示例中,您将在 custid 上创建一个聚集索引,该索引将涵盖以下查询:

select FirstName from Customers where custid = 12

这也有助于加入(例如从客户到订单)。

【讨论】:

以上是关于如何将非聚集索引变成覆盖索引的主要内容,如果未能解决你的问题,请参考以下文章

具有包含性列的索引

08.索引-非聚集索引-联合索引覆盖索引

创建带包含列的索引 sqlserver

一文总结分析聚集索引非聚集索引覆盖索引的工作原理!

索引的访问-SQL Server

名词解释与区分聚集索引非聚集索引主键索引唯一索引普通索引前缀索引单列索引组合索引全文索引覆盖索引