2009-05-27 67 views
4

目前我們有許多使用主鍵上的newid()的表。這導致大量的碎片。所以我想改變列來使用newsequentialid()來代替。將newid()更改爲現有表上的newsequentialid()

我想現有的數據將保持相當分散的狀態,但新數據的分散性較差。這意味着我應該等待一段時間,然後再將PK索引從非羣集更改爲羣集。

我的問題是,有沒有人有這樣做的經驗?有什麼我忽略了我應該小心嗎?

回答

3

如果您切換到sequentialguids 重新組織一次索引,您將消除碎片。我不明白你爲什麼要等到零碎的頁面鏈接在連續的範圍內重新排列。

這就是說,你有沒有做過任何測量,以表明碎片實際上正在影響你的系統?只是看一個索引,看到'分散75%'而不是意味着訪問時間受到影響。還有更多因素起作用(緩衝池頁面預期壽命,讀取率與寫入率,順序操作的位置,操作的併發性等)。雖然從guid切換到順序guid通常是安全的,但您仍然可能會引入問題。例如,您可以看到插入密集型OLTP系統的頁面鎖定爭用,因爲它會在插入點積累時創建一個熱點頁面。

+0

感謝雷木思 - 有趣的評論。我之前曾聽說過'頁面鎖定爭用',但似乎很少在提及和反對GUID的論據中提及。 你說得對,我在轉換到聚集索引之前想要等待的想法可能是錯誤的。 – cbp 2009-05-27 01:59:49

-4

如果這是SQL Server,則通過調用newid()來生成Guid。這對主鍵不太合適。爲主鍵使用整數標識列,並使Guid成爲代理鍵(以及行GUID列)。

+0

這就是爲什麼他要問切換到newsequentialid()來代替。 – 2009-05-27 01:32:02

4

您可能會考慮使用comb guids,而不是newsequentialid。

cast(
    cast(NewID() as binary(10)) + 
    cast(GetDate() as binary(6)) 
as uniqueidentifier) 

梳GUID是與當前日期時間的非隨機性沿着純粹隨機的GUID的組合,以使得梳的GUID連續世代彼此接近並且通常以升序排列。 Comb guid與newsequentialid相比有很多優點,包括它們不是黑盒子的事實,您可以在默認約束之外使用此公式,並且可以在SQL Server之外使用此公式。

+0

我想過他們,但我想我寧願選擇'支持'功能。我想我可以在理論上將表從newid()切換到COMBs,但沒有問題,因爲數據類型是相同的。 – cbp 2009-05-27 02:01:21

0

謝謝你,yfeldblum!您對COMB GUID的簡單而簡潔的解釋確實幫助了我。實際上,我正在考慮做與本文相反的內容:由於我試圖將SQL Server 2012數據庫遷移到Azure,因此我不得不依靠newsequentialid(),並且newsequentialid()函數在那裏不受支持。

我能夠改變我所有的表PK違約梳理的GUID,語法如下:

ALTER TABLE [dbo].[Company] 
ADD CONSTRAINT [DF__Company__Company_ID__72E6D332] 
    DEFAULT (CONVERT([uniqueidentifier],CONVERT([binary](10),newid(),0)+CONVERT([binary](6),getdate(),0),0)) FOR [CompanyId] 
GO 

我SQL2012數據庫現在快樂地生活在Azure雲。

相關問題