非唯一列上的非聚集索引

简介:

我们来看一个例子。

复制代码
1 SELECT * INTO dbo.SalesOrderDetail FROM AdventureWorks2008r2.Sales.SalesOrderDetail
2 GO
3 CREATE UNIQUE CLUSTERED INDEX ix_SalesOrderDetail ON dbo.SalesOrderDetail(SalesOrderDetailID)
4 GO
5 CREATE INDEX Ix_ProductId ON SalesOrderDetail(ProductId,Salesorderid)
复制代码

我们创建了SalesOrderDetail表的副本,在SalesOrderDetailId 列定义了唯一聚集索引,在ProductId和SalesOrderId列定义了非聚集索引。注意,在创建非聚集索引的时候,我有意回避了使用Unique关键字,即使这个非聚集索引键是唯一的。

我们用DBCC IND看下非聚集索引的页面分配情况,并找出根页。

复制代码
1 TRUNCATE TABLE dbo.sp_table_pages
2 INSERT INTO sp_table_pages EXEC('DBCC IND(IndexDB,SalesOrderDetail,2)')
3 GO
4 
5 SELECT * FROM dbo.sp_table_pages ORDER BY IndexLevel DESC --根节点/索引页
复制代码

可以看出,5128页是我们的根页。我们用DBCC PAGE看下5128页信息还有叶子页的信息。

复制代码
1 DBCC TRACEON(3604)
2 DBCC PAGE(IndexDB,1,5128,3)--根页
3 
4 DBCC TRACEON(3604)
5 DBCC PAGE(IndexDB,1,3760,3)--叶子页
复制代码

我们来看上半部分的根页,聚集键(SalesOrderDetailid)被加到了根页。如果你和索引深入浅出:非聚集索引的B树结构在聚集表里的根页比较,会发现那里的根页里没有聚集键,只有在叶子页里才可以找到聚集键。在你把非聚集索引定义为唯一或非唯一(unique or non unique)时,叶子层的页结构不会发生改变。

我们看下堆表的情况。

复制代码
 1 SELECT * INTO dbo.SalesOrderDetailHeap FROM AdventureWorks2008R2.Sales.SalesOrderDetail
 2 GO
 3 CREATE INDEX Ix_ProductId ON SalesOrderDetailHeap (ProductId,Salesorderid)
 4 GO
 5 SELECT index_id FROM sys.indexes WHERE name='Ix_ProductId' AND 
 6 OBJECT_NAME(OBJECT_ID)='SalesOrderDetailHeap'
 7 GO
 8 DBCC ind('IndexDB','SalesOrderDetailHeap',2)
 9 GO
10 TRUNCATE TABLE dbo.sp_table_pages
11 INSERT INTO sp_table_pages EXEC('DBCC IND(IndexDB,SalesOrderDetailHeap,2)')
12 SELECT * FROM dbo.sp_table_pages ORDER BY IndexLevel DESC --根节点/索引页
13 DBCC TRACEON(3604)
14 DBCC PAGE(IndexDB,1,1192,3)--根页
15 
16 DBCC TRACEON(3604)
17 DBCC PAGE(IndexDB,1,1096,3)--叶子页
复制代码

在根页我们看到多了Heap RID列,如果你回去看看索引深入浅出:非聚集索引的B树结构在堆表,你会发现Heap RID列只在叶子层里的页出现,不在根页出现。在你把非聚集索引定义为唯一或非唯一(unique or non unique)时,叶子层的页结构不会发生改变。

你可能已经注意到,在我们上述的例子里,即使非聚集索引键是唯一的,SQL Server还是只当它是非聚集索引,因为当我们创建非聚集索引时没加unique关键字。在索引所有层增加聚集键(或Heap RID)可能会增加更多的索引层IO操作,这个看聚集键的大小而定。因此在所有情况下,我们定义非聚集索引时,考虑选择唯一列(或多列)作为非聚集键非常重要。 


本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4506883.html,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 监控 数据库
什么是聚集索引和非聚集索引?
【8月更文挑战第3天】
526 5
|
存储 Oracle 关系型数据库
主键索引是聚集索引还是非聚集索引
在聚簇索引中,主键索引的叶子节点存储的就是数据行本身,因此主键索引也被称为聚簇索引。在这种情况下,主键索引的物理顺序与数据行的物理顺序是一致的,这样可以提高查询性能和范围查询的效率。
118 0
|
SQL 关系型数据库 MySQL
表索引——多列索引
前言 多列索引,是指在创建索引时所关联的字段不是一个字段,而是多个字段,虽然可以通过所关联的字段进行查询,但是只有查询条件中使用了所关联字段中的第一个字段,多列索引才会被使用。
|
存储 关系型数据库 MySQL
mysql索引(三)聚集索引与非聚集索引(辅助索引)
Mysql中常用的两个存储引擎innodb和mysiam的索引是不同的。 聚集索引就是以主键创建的索引 非聚集索引就是除了主键以外的索引。非聚集索引也叫做二级索引,不用纠结那么多名词,将其等价就行了。非聚集索引在建立的时候也未必是单列的,可以多个列来创建索引。
283 0
mysql索引(三)聚集索引与非聚集索引(辅助索引)
|
存储 SQL 关系型数据库
mysql索引(六)主键索引
主键索引(PRIMARY):它是一种特殊的唯一索引,不允许有空值。 主键索引,简称主键,原文是PRIMARY KEY,由一个或多个列组成,用于唯一性标识数据表中的某一条记录。一个表可以没有主键,但最多只能有一个主键,并且主键值不能包含NULL。
1372 0
mysql索引(六)主键索引
|
关系型数据库 MySQL C语言
mysql索引(五)联合索引
联合(组合)索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
277 0
mysql索引(五)联合索引
|
存储 关系型数据库 MySQL