如何将非聚集索引变成覆盖索引
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
这也有助于加入(例如从客户到订单)。
【讨论】:
以上是关于如何将非聚集索引变成覆盖索引的主要内容,如果未能解决你的问题,请参考以下文章