這聽起來像是將羣集密鑰添加到非唯一非聚集索引的(全部)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
上的唯一索引不包含記錄指針,而只包含索引列本身的值。
這又是因爲使用唯一索引,索引列的值足以在索引中定位其節點,而使用非唯一索引則不是。
您需要了解基本知識,然後才能討論中間信息。 – PerformanceDBA 2010-10-30 07:46:17
擴大我的答案。 – PerformanceDBA 2010-10-30 08:27:05
不知道整個歷史,但這個問題是完全有效的,很有趣。 – Quassnoi 2010-10-30 09:52:18