【问题标题】:Why is there no heap rid present in the unique non-clustered index root page but is present in root page of non-unique non clustered index?为什么唯一非聚集索引根页中没有堆清除,但非唯一非聚集索引的根页中存在堆清除?
【发布时间】: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


【解决方案1】:

请阅读这些文章(均由 Klaus Aschenbrenner 撰写):

摘录:

"这里的结论是,非唯一聚集索引上的唯一非聚集索引只使得聚集索引的叶级有4个字节的开销,因为这里SQL Server直接指向了正确的记录。唯一非聚集索引的非叶级别不涉及额外开销。”

因为它直接指向正确的记录,所以没有堆 RID。

由于唯一键本身是行的唯一标识符,因此唯一 CI 或唯一 NCI 中不存在 RID。当该行中不存在唯一键时会发生 RID,因此 SQL Server 添加行标识符 (RID) 来定位该行并爬上 B 树。

所以 RID 与 CI 或 NCI 无关。 RID 与行的唯一性有关。

【讨论】:

  • @KumarHarsh- 两个博客都是由同一个人写的。这里的问题仅与根级索引页面有关,与叶级页面无关。它是我有疑问的根页面的诊断。
  • @100pipers,看看我的最后一段。
  • @kumarharsh- 所以我们是说因为非唯一非聚集索引可以有 100 个具有相同 id 的键,比如 1,为了区分所有这些 1,sql server 附加了一个 rid 吗?谢谢。
  • @100pipers , 绝对是。sqlservercentral.com/blogs/practicalsqldba/2013/03/24/… 然后也阅读第 4 部分
猜你喜欢
  • 2014-11-04
  • 2011-04-17
  • 1970-01-01
  • 2019-10-28
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-13
  • 1970-01-01
相关资源
最近更新 更多