2010-10-30 38 views
0

考慮聚集表,
Quassnoi寫(在回答最後一個短語):爲什麼要將聚簇索引鍵添加到NCI上的所有(中間)節點?

這聽起來像是將羣集密鑰添加到非唯一非聚集索引的(全部)indermediate節點中。並且通過相同的邏輯,在非集羣表(?)的情況下將RID添加到中間節點中(?)

它的目的是什麼?

更新:
目前這個問題有9票:-5,+ 4,從單純的匿名開始-3), 正確答案矛盾最MSDN文檔。
它的價值實際上並不在於它本身,而在於如何解決這類與SQL Server內部相關的問題,這些問題在文檔中可能相互矛盾,也可能不正確或不充分。

UPDATE2: @Quassnoi,
謝謝您的回答豐富研究自己不問愚蠢的問題我的能力。

DBCC IND()不輸出PageID。我不清楚它的PagePID(來自DBCC IND的輸出)對應於DBCC DBCC Page()的輸出中的PageID。
我對它們的使用(和內部研究/調查)或其他選擇有更多的問題。我不確定爲什麼這類問題在此處被視爲垃圾郵件。
你能告訴我適當的論壇/董事會這種類型的問題(在SQL Server內部)?

+1

您需要了解基本知識,然後才能討論中間信息。 – PerformanceDBA 2010-10-30 07:46:17

+0

擴大我的答案。 – PerformanceDBA 2010-10-30 08:27:05

+2

不知道整個歷史,但這個問題是完全有效的,很有趣。 – Quassnoi 2010-10-30 09:52:18

回答

4

這聽起來像是將羣集密鑰添加到非唯一非聚集索引的(全部)indermediate節點中。並且通過相同的邏輯,在非集羣表(?)的情況下將RID添加到中間節點中(?)

是的,這是真的。

這樣做是爲了提高索引的可維護性。假設您在column,1,000,000記錄中有一個輔助(非羣集)索引,並帶有column = 1並且想要刪除其中一個記錄。

該記錄也需要從索引中刪除。

要找到要刪除的記錄,應該在索引上執行B-Tree搜索。但是如果分支節點沒有存儲行指針的值(不管是聚簇密鑰還是RID),引擎將不得不掃描所有1M記錄以確定要刪除的記錄。

如果輔助鍵是UNIQUE,那麼column的值就足以在索引中唯一地定位節點,因此不需要在分支節點中存儲行指針(這就是爲什麼不存儲它們的原因)。

這種討論也可以是有趣的你:

http://www.sqlservercentral.com/Forums/Topic714684-1545-6.aspx

更新:

要檢查的分支節點的內容,你可以使用DBCC IND

CREATE TABLE t_clustered (id INT NOT NULL PRIMARY KEY, nval INT, uval INT) 
CREATE TABLE t_nonclustered (id INT NOT NULL PRIMARY KEY NONCLUSTERED, nval INT, uval INT) 

CREATE INDEX ix_clustered_nval ON t_clustered (nval) 
CREATE UNIQUE INDEX ux_clustered_uval ON t_clustered (uval) 
CREATE INDEX ix_nonclustered_nval ON t_nonclustered (nval) 
CREATE UNIQUE INDEX ux_nonclustered_nval ON t_nonclustered (uval) 
; 
WITH q(id) AS 
     (
     SELECT 1 
     UNION ALL 
     SELECT id + 1 
     FROM q 
     WHERE id < 10000 
     ) 
INSERT 
INTO t_clustered 
SELECT id, (id - 1)/10 + 1, id 
FROM q 
OPTION (MAXRECURSION 0) 
; 
WITH q(id) AS 
     (
     SELECT 1 
     UNION ALL 
     SELECT id + 1 
     FROM q 
     WHERE id < 10000 
     ) 
INSERT 
INTO t_nonclustered 
SELECT id, (id - 1)/10 + 1, id 
FROM q 
OPTION (MAXRECURSION 0) 

-- Replace mydb with your database name 

DBCC IND (mydb, t_clustered, -1) 
DBCC IND (mydb, t_nonclustered, -1) 

在這些命令的輸出中,您應該使用搜索記錄PageType = 2(索引頁)和IndexLevel > 0(非葉節點)並找到它們的PageID

在我的情況下,我得到了以下PageID:21074,21076,21105,21107。注意它們是網站特定的:您將擁有其他值。

那麼你應該使用DBCC PAGE檢查這些網頁的內容:

DBCC PAGE (mydb, 1, 21074, 3) 
DBCC PAGE (mydb, 1, 21076, 3) 
DBCC PAGE (mydb, 1, 21105, 3) 
DBCC PAGE (mydb, 1, 21107, 3) 

FileId PageId  Row Level ChildFileId ChildPageId nval (key) id (key) KeyHashValue 
FileId PageId  Row Level ChildFileId ChildPageId uval (key) KeyHashValue 
FileId PageId  Row Level ChildFileId ChildPageId nval (key) HEAP RID (key)  KeyHashValue 
FileId PageId  Row Level ChildFileId ChildPageId uval (key) KeyHashValue 

我們看到,nval非唯一二級索引的非葉節點包含記三分球(id (PRIMARY KEY CLUSTERED)RID,適當),而那些uval上的唯一索引不包含記錄指針,而只包含索引列本身的值。

這又是因爲使用唯一索引,索引列的值足以在索引中定位其節點,而使用非唯一索引則不是。

1

你在問什麼別人沒有任何理解主題(IT; B-Trees;索引結構)的話他們說了什麼,做了什麼聲明。這是一個答案服務,而不是教程服務。

「這聽起來像是聚集鍵被添加到(全部)非唯一的非聚集索引的indermediate節點」

號Quassnoi說這樣的事。你不能接受陳述(在上下文中的回答;問題),並孤立地評估他們。 CI密鑰是只有適用於葉級別,而不是「中間節點」。

「並且由相同的邏輯的RID被添加到indermediate節點在非聚集表(?)的情況下,」

邏輯?沒有了。大象尾巴是由粗長頭髮組成的,並不意味着軀幹也是由頭髮製成的。

問一個非唯一的非聚集索引的非葉節點的另一個問題。對於這個非問題,我有點不感興趣。

答案。對於您現在一貫明顯的理解水平,非聚簇索引具有完整的聚簇鍵值作爲葉級別的條目。期。故事結局。這沒什麼大不了的,因爲(a)步驟的數量是相同的(b)CI指數(而不是葉)將無論如何將在緩存中,並且因此非常快速,直到最後(葉級)才需要磁盤訪問。

NCI鍵查找,沒有CI: 索引查找 - > RID - >數據行查找 - >數據行

NCI鍵查找CI: 索引查找 - > CI鍵 - >聚集索引查找 - > Data Row

它的目的是什麼?

表現。所有供應商都明白,查詢激活的功能鏈中最慢的組件是磁盤,它是具有移動部件的唯一組件。他們都盡力避免磁盤訪問,並提高性能。索引本身是自20世紀60年代以來避免磁盤訪問的最基本結構。基本的B-Tree從那時起一直沒有改變,它只有一百萬個小小的進步。 (a)有自己的一些特殊技術,可以增強(在不改變我在帖子中描述的基本操作的情況下)操作,並且(b) )在MicroShifty世界中,它一直在變化,因爲這些增強並不是真正的增強。需要指出的是,極低的水平與理解指數如何工作無關;或者CI或NCI是否適合您的特定用途;或每個的優點/缺點。

我已經確定,爲了協助你,不要涉及到較低的層次,直到你理解了基礎知識,更高的層次......如果你這樣做,你會迷路,這將是一個障礙達到你提出的學習目的。如這裏所證明的。再次。

+2

我喜歡你的答案和upvoted他們所有。沒有必要繼續發送我來研究基礎知識,並在每個答案中評估理解水平(僅僅通過問題?!)。我讀了所有,理解,接受並已經開始研究這些基礎知識和主題。謝謝! – 2010-10-30 14:56:31

相關問題