6.2.2.1 聚集索引

 

聚集索引是一种特殊的平衡树。这种平衡树与前面的平衡树相比,差别在于索引的叶子级。在聚集索引中,叶子并不包括索引键和指针;它们就是数据本身。这个差异意味着数据并不存储在结构中。它们存储在索引的叶子级,并按索引键进行排序。这种设计具有两个优点:

l          SQL Server不需要依据指针来访问数据。数据直接存储在索引中。

l          数据依据索引键排序,这是主要的优点。无论什么时候,只要SQL Server需要依据索引键排序数据,都不必再执行排序操作,因为数据已经排好序了。

由于数据包含在聚集索引之中,因此只能为每个表定义一个聚集索引。以下语法用于创建一个聚集索引:

 

CREATE [ UNIQUE ] CLUSTERED INDEX index_name

     ON <object> ( column [ ASC | DESC ] [ ,...n ] )

 

可以看出,可以定义索引为“unique(惟一的),这意味着两个行不能有相同的索引键值。

 注意     SQL Server在一个表上创建主键或惟一性约束的时候会创建一个惟一索引。在主键定义后,如果在表中还没有定义聚集索引,SQL Server会默认为这个主键建立聚集索引。创建主键或者惟一约束时定义的索引的类型可以这样指定:在CREATEALTER TABLE 语句中使用CLUSTEREDNONCLUSTERED 关键字。

Ø       创建并使用聚集索引

1.    打开SQL Server Management Studio。打开“新建查询”窗口并更改数据库上下文为“AdventureWorks”。

2.    键入并执行以下语句在Orders表上创建一个聚集索引。此示例的代码包含在示例文件CreatingAndUsingClusteredIndexes.sql中。

 

CREATE UNIQUE CLUSTERED INDEX CLIDX_Orders_SalesOrderID

    ON dbo.Orders(SalesOrderID)

 

3.    现在再执行前面执行过的两个SELECT语句来检验区别。要保证在执行时包括实际的执行计划。

 

SET STATISTICS IO ON;

 

SELECT * FROM dbo.Orders;

 

SELECT * FROM dbo.Orders

WHERE SalesOrderID =46699;

 

SET STATISTICS IO OFF;

 

4.    切换到“执行计划”选项卡。

6.6  “执行计划”选项卡


 

       可以看出,这里的SQL Server不再使用表扫描。现在,由于数据不再存储在堆结构中,因此SQL Server执行了索引操作。执行计划表明将使用两个主要的索引操作,它们是:

l          索引扫描  读取表中的所有数据,通过索引的叶子所进行的扫描。由于第一个SELECT语句没有WHERE子句,因此SQL Server知道需要获取所有数据,这些数据存储在索引的叶子上。

l          索引查找  SQL Server查找特定值的一个操作。这个操作起始于索引的根并将查询值传递给索引的分支以进行查询。

       这两个操作同样可以组合起来获取一个特定范围的数据。在这种局部扫描操作中,SQL Server会首先找到范围的起始值,然后持续扫描到范围的终点值结束。

5.    切换到“消息”选项卡,如图6.7所示。

6.7  “消息”选项卡

       可以看出,第一个SELECT语句执行了与使用堆结构进行表扫描时相同的页读取操作。这并不奇怪,因为SELECT语句要求获取所有数据。因此SQL Server不得不获取所有数据。但是,第二个SELECT语句只进行了两次页读取,这比前面有了很大的改进,少读了178页。SQL Server只需在索引上进行查找,相较于在所有数据页上进行扫描,它需要的I/O操作要少得多。

6.    键入以下SELECT语句,它会按顺序获取数据。图6.8显示了执行结果。然后按“Ctrl+L”来获取估计的执行计划。

 

SELECT * FROM dbo.Orders

ORDER BY SalesOrderID;

 

SELECT * FROM dbo.Orders

ORDER BY OrderDate;

可以看出,第一个语句只执行了一次聚集索引扫描而并没有对数据进行排序。这是因为这个列是一个聚集索引键列,数据已经根据SalesOrderID进行了排序。因此,SQL Server为了按顺序获取行只需要在叶子扫描数据并返回结果。

对于第二个查询,数据必须在获取之后进行排序。因此,在聚集索引扫描操作之后有一个在OrderDate列上进行的排序操作。由于排序操作是非常昂贵的操作,因此第二个操作的开销占据了整个查询开销的93%。所以,对于经常需要进行排序的列,最好为其定义聚集索引。经常需要进行聚合分组的列也如此,因为在进行聚合数据的时候,SQL Server首先需要依据分组条件对其进行排序。

6.8  执行结果

现在要在OrderDetails表上构建一个复合索引。一个复合索引是一个为多个列定义的索引。索引键将依据第一个索引键进行排序,然后是第二个,依次类推在使用两个以上的一起作为条件进行查询的时候,或者在需要通过多列来惟一确定一行的时候,这种索引是非常有用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值