SQL Server 索引优化——重复索引(部分重复)
前文给出了查询完全重复索引方法,但更多的情况下,是多个管理员,根据单个或部分查询,创建其各自需要的索引,而没有考虑整体情形,就会出现大量的部分重复索引,这对OLAP来说没有较大的影响,但对于OLTP系统,频繁的数据变更就会造成大量的性能消耗,同时也会增加存储的压力。所以对于这部分的索引的优化也显得非常有重要。我们可以这样理解部分重复索引,即同一列(或列集,不包含聚集索引的键列)在不同索引的第一键列(第二、第三……)中重复出现,其他部分不同。部分重复索引的构成比较复杂,没有办法给出统一脚本,只能通过一个个简单的例子进行说明。
先创建测试表,脚本如下:
CREATE TABLE Member
(
MemberNo INT IDENTITY,
FirstName VARCHAR(30) NOT NULL,
LastName VARCHAR(30) NOT NULL,
RegionNo INT
);
为说明这个问题,下面考虑两个查询,并单独创建各自需要的索引。
SELECT
LastName
FROM Member
WHERE FirstName='jack';
CREATE INDEX MemberIndex1
ON Member(FirstName)
INCLUDE(LastName);
GO
CREATE INDEX MemberIndex2
ON Member(FirstName)
INCLUDE(RegionNo);
GO
SELECT
RegionNo
FROM Member
WHERE FirstName='jack';
可以看到MemberIndex1、MemberIndex2的键列均为FirstName,而前者的包含列为LastName,后者的包含列为RegionNo。因为包含列中的顺序不会影响查询优化器对索引的使用,所以可以这样消除重复索引,我们删除索引MemberIndex2,重建索引MemberIndex1,包含列同时包含原两个索引包含列中的LastName和RegionNo,脚本如下:
DROP INDEX Member.MemberIndex2;
CREATE INDEX MemberIndex1 ON Member(FirstName)
INCLUDE(LastName,RegionNo)
WITH (DROP_EXISTING=ON);
重建索引后,再次执行两个查询,查看它们的执行计划如下:
可以看到两个查询都使用新的索引进行索引查找。这样我们节省了一个索引维护的开销,同时减少了索引中重复字段的存储空间。
部分重复索引可能不尽相同,如有兴趣,欢迎讨论。
如果喜欢,可以搜索关注 MSSQLServer 公众号,将有更多精彩内容分享: