【发布时间】:2017-04-23 07:19:40
【问题描述】:
我正在做一些分析并试图收集对 SQL Server 2008 上唯一和非唯一非聚集索引的一些理解?在一个技术博客之后,我做了以下事情。
USE TEST
CREATE TABLE "CustomersHeap" (
"CustomerId" INT NOT NULL,
"CustomerName" CHAR(100) NOT NULL,
"CustomerAddress" CHAR(100) NOT NULL,
"Comments" CHAR(189) NOT NULL
)
;
USE TEST
DECLARE @i INT = 1 WHILE (@i <= 80000) BEGIN
INSERT INTO dbo.CustomersHeap VALUES
(
@i,
'CustomerName' + CAST(@i AS CHAR),
'CustomerAddress' + CAST(@i AS CHAR),
'Comments' + CAST(@i AS CHAR)
) SET @i += 1
END
-- Create a unique non clustered index
CREATE UNIQUE NONCLUSTERED INDEX IDX_UniqueNCI_CustomerID
ON Test.dbo.CustomersHeap(CustomerId)
-- Create a non-unique non clustered index
CREATE NONCLUSTERED INDEX IDX_NonUniqueNCI_CustomerID
ON Test.dbo.CustomersHeap(CustomerId)
--Get indexes
select * from sys.indexes where object_id=OBJECT_ID('Test.dbo.CustomersHeap')
--After figuring out index and child pages using DBCC IND
DBCC TRACEON(3604)
--UniqueNonClusteredIndex root page
DBCC PAGE(Test, 1, 4160, 3)
--NonUniqueNonClusteredIndex root page
DBCC PAGE(Test, 1, 4416, 3)
第一页语句的输出不包含名为“HEAP RID”的列,而第二页语句的输出则包含。我无法理解为什么?特别是当所有行都有 ChildPageId 的信息并且它们应该正确包含“HEAP RID”时。
这些额外的列增加了非唯一非聚集索引的根页面的大小。
第一页语句的输出列 FileId,PageId,Row,Level,ChildFileId,ChildPageId,CustomerId,KeyHashValue
第二页语句的输出列 FileId,PageId,Row,Level,ChildFileId,ChildPageId,CustomerId,HEAP RID,KeyHashValue
【问题讨论】:
-
我对此的理解非常不完整,但我的猜测是,也许Heap RID被添加到非唯一索引中以使其(或者更确切地说,其中的键)在内部唯一?跨度>
-
也就是说,在唯一索引的情况下,SQL Server 知道
CustomerId本身就足以定位具有完整数据的特定表行。在非唯一索引的情况下,原始表中可能有几行具有相同的CustomerId,因此 SQL Server 通过添加内部(和唯一)RID 来使索引中的“外键”唯一,即。通过将索引键转换为复合键。
标签: sql-server non-clustered-index