SQL Server索引进阶第二篇:深入非聚集索引
索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其反,可以说“成也索引,败也索引”。
本系列文章来自Stairway to SQL Server Indexes
IF EXISTS ( SELECT *
FROM sys.tables
WHERE OBJECT_ID = OBJECT_ID('dbo.Contacts_index') )
DROP TABLE dbo.Contacts_index ;
GO
IF EXISTS ( SELECT *
FROM sys.tables
WHERE OBJECT_ID = OBJECT_ID('dbo.Contacts_noindex') )
DROP TABLE dbo.Contacts_noindex ;
GO
SELECT *
INTO dbo.Contacts_index
FROM Person.Contact ;
SELECT *
INTO dbo.Contacts_noindex
FROM Person.Contact ;
代码2.1:制作Person.Contact 表的副本
Contacts表内的部分数据如下所示:
非聚集索引条目
如下代码段在Contacts_index表上创建名为FullName的非聚集索引.
CREATE INDEX FullName
ON Contacts_index
( LastName, FirstName ) ;
SET STATISTICS io ON
SET STATISTICS time ON
因为AdventureWorks数据库的Contact表中仅有19972行数据,因此很难从时间统计中看出倪端,测试的大部分执行语句CPU时间都是0,因此就不再显示CPU时间了。仅仅显示能反映出可能读取的页数的IO统计。这个值可以帮助我们对比同样查询在存在非聚集索引和不存在非聚集索引的情况下比较同样查询语句的性能。如果你想做一些更接近实际的CPU时间测试,在文章的末尾可以找到百万级别的Contact表的创建代码。下面的结论仅仅是针对标准的19972行的Contact表。
测试聚合覆盖查询
我们最后的例子是聚合查询,也就是查询中使用了聚合。下面的查询根据LastName和FirstName进行分组来找到姓名完全相同的人.
部分查询结果如下:
Steel Merrill 1
Steele Joan 1
Steele Laura 2
Steelman Shanay 1
Steen Heidi 2
Stefani Stefano 1
Steiner Alan 1
查询执行的详细信息见表2.4
SQL语句
SELECT LastName, FirstName, COUNT(*) as 'Contacts'
FROM dbo.Contacts – 分别执行在Contacts_noindex表和Contacts_index表上
WHERE LastName LIKE 'Ste%'
GROUP BY LastName, FirstName
SELECT LastName, FirstName, MiddleName, COUNT(*) as 'Contacts'
FROM dbo.Contacts
--分别执行在Contacts_noindex表和Contacts_index表上
WHERE LastName LIKE 'Ste%'
GROUP BY LastName, FirstName, MiddleName