Sql-Server

主鍵的聚集索引與非聚集索引

  • August 31, 2018

我有一張大桌子,裡面有大約 1900 萬條記錄。

主鍵是一個uniqueidentifier名為的列ID,並且該列上有一個非聚集索引。應用程序生成這些 GUID 值。

該表目前沒有聚集索引。

我正在考慮從非聚集索引更改為聚集索引,因為該表目前沒有聚集索引。我想知道這樣做的利弊是什麼,或者我應該這樣做嗎?

  1. 保持原樣
  2. 查找另一列以在其上創建聚集索引
  3. 將此 ID 列從非聚集索引更改為聚集索引。

我們每天收到大約 50K 的插入,沒有刪除也沒有更新。如果您需要任何其他詳細資訊,請告訴我。

該表總共有 24 列和 5 個沒有聚集索引的非聚集索引:

  • 索引 1- ID 上的 PK ( uniqueidentifier)
  • 索引 2- 時間戳 ( datetime)
  • 索引 3- 雜湊列 ( nvarchar(64))
  • 索引 4- 覆蓋索引 4 列
  • 索引 5- 覆蓋索引 6 列

我從別人那裡繼承了數據庫。應用程序將此 GUID 用作與相應子表中匹配外鍵的關係的主鍵,因此查詢使用uniqueidentifier連接中的 id。

如何確定我的 GUID 是否按順序生成?它們看起來並不相似。一些範例按以下順序排列createddate

24A689A0-831E-4670-9204-766256C58E43
ED001C69-11BA-430D-ACF9-3C3CADF3B400
768E5497-4F48-4C65-87D9-E9C27066708E

做一些研究,似乎uniqueidentifier列不是聚集索引的好候選者,所以我想知道是否需要:

  1. 查看幾列以在這些列上創建複合聚集索引或
  2. 沒有聚集索引的生活
  3. 還有什麼?

讓我知道我是否可以提供任何其他詳細資訊。如果有人可以就做出此決定的一些考慮因素給我一些指導,我將不勝感激。

除非您切換到順序 GUID 生成,否則您不希望 GUID 作為聚集索引鍵。所以你的選擇是

  1. 使 ID 列成為聚集索引鍵。這將優化 ID 上的連接和查找,但聽起來這些很少見。

  2. 對於 SQL 2016+,將堆替換為聚集列儲存索引。這會壓縮數據並優化表掃描,可能在某種程度上您可以刪除一些其他索引。

  3. 選擇您最常用的非聚集索引並將其設為聚集索引。

  4. 將其保留為堆。

在任何情況下,使用 GUID 作為外鍵的“子表”可能會受益於將該外鍵列作為其聚集主鍵中的前導列。

我不建議將此uniqueidentifier欄位用作此表的集群鍵。你提到:

我們每天收到大約 50K 的插入,沒有刪除也沒有更新

將此作為表的聚集索引意味著整個表將按該欄位排序。因此,每次插入完成時,SQL Server 都需要查找索引中的那個位置,然後將新行插入到該位置的表中。

如果數據頁上沒有空間需要插入新行,則必須移動數據以騰出空間。

理想情況下,您的集群密鑰應該很小、唯一且不斷增加。絕對不符合“uniqueidentifier不斷增加”的標準。


由於聽起來您工作負載的“寫入”部分是僅插入的(沒有刪除或更新),因此堆(根本沒有聚集索引 - 事物的目前狀態)可能是該表的不錯選擇!只要任何 SELECT 查詢的執行都可以接受。

如果您遇到慢速選擇查詢的問題,您可能需要添加額外的非聚集索引來支持它們 - 或者選擇滿足我上面提到的要求的聚集索引。

引用自:https://dba.stackexchange.com/questions/216258