5

我正在開發一個新數據庫的數據庫標準。我們試圖定義的一個事項是與UniqueIdentifiers相關的主鍵和聚簇索引規則。 (注意:我不想討論使用UniqueIdentifier作爲主鍵或聚簇索引的優缺點,網上有很多關於這個的信息,這是而不是那個討論。 )UniqueIdentifier上的NewSequentialId集羣索引

所以這裏是有我擔心的情況:

說我有一個表,一個唯一標識符爲聚集索引和主鍵。讓我們稱之爲ColA。我將ColA的默認值設置爲NewSequentialId()。

使用NEWSEQUENTIALID()我插入三個連續行:

{72586AA4-D2C3-440D-A9FE-CC7988DDF065}
{72586AA4-D2C3-440D-A9FE-CC7988DDF066}
{72586AA4-D2C3- 440D-A9FE-CC7988DDF067}

然後我重新啓動我的服務器。 docs for NewSequentialId說:「重新啓動Windows後,GUID可以從較低範圍重新開始,但仍然是全局唯一的。」

所以下一個起點可以低於前一個範圍。

所以重啓後,我插入3個值:

{35729A0C-F016-4645-ABA9-B098D2003E64}
{35729A0C-F016-4645-ABA9-B098D2003E65}
{35729A0C-F016- 4645-ABA9-B098D2003E66}

(我不確定數據庫中guid是如何表示的,但我們假設這個從3開始,以前從7開始,3開始比「小」 7個)。

當你做一個插入是在聚集索引中間,索引的重新映射必須發生。 (至少讓我的DBA告訴我)每次重新啓動時,我都有可能讓我的新UniqueIdentifier範圍正好處於其他先前範圍的中間。

所以我的問題是:由於下一組UniqueIdentifiers將小於最後一組,將每個插入導致我的聚簇索引洗牌?

如果不是,爲什麼? SQL Server是否知道我正在使用NewSequentialId?它是如何彌補的?

如果不是,那麼它如何知道我將接下來插入什麼?也許下一百萬個插入將從3開始,或者也許他們將從7開始。它是如何知道的?

還是不知道,只是保持一切順序。如果是這樣的話,一次重啓可能會嚴重影響性能。 (這讓我覺得我需要自己定製的NewSequentialId,它不受重新啓動的影響。)那是正確的嗎?還是有一些我不知道的魔法?

編輯:我的標準強烈建議不要將GUID作爲聚簇索引。正如我上面所說,這是一個糟糕的主意,原因很多。我想知道這是否是另一個原因。

+0

「如果是這樣,那麼一次重啓可能會嚴重影響性能。」 - 這就是爲什麼你想要使用int IDENTITY(),即使你不想聽到它。 – HardCode

回答

1

通常情況下,您將使用適當的FILL FACTOR創建索引,以在這種情況下爲所有頁面留出空白區域。話雖如此,一旦空白空間被填滿,聚集索引就會重新排序。

我知道你不想討論使用GUID作爲聚簇鍵,但這是不推薦的做法之一。

會發生什麼情況是,您將會有越來越多的頁面拆分,這會導致在保持插入行時出現非常高級別的碎片,並且您需要以更高的頻率重建索引以保持表現符合。

有關該主題的全力救治,也沒有更好的源比

Kim
Tripp's
Blog

作爲一個方面說明,當你正在考慮創建自己的NEWSEQUENTIALID創作功能,你可能有一個設計問題,應該重新考慮你的計劃。

+0

我已經閱讀過她的幾篇文章。我的標準強烈建議不要將GUID作爲聚集索引。我正在試圖爲此建立一個案例。 (因此,這個問題。) – Vaccano

+0

一旦達到填充因子,每個插入會導致重新排序? – Vaccano

+0

這取決於。填充因子是按頁面顯示的,因此一旦頁面已滿,則是。如果他們需要插入的頁面已滿,所有後續插入將導致重新排序。 – JNK