什麼時候應該將主鍵聲明為非聚集的?
在為我之前提出的另一個問題創建測試數據庫時,我記得可以聲明主鍵
NONCLUSTERED
什麼時候使用
NONCLUSTERED
主鍵而不是CLUSTERED
主鍵?提前致謝
問題不是“PK 何時應該是 NC”,而是您應該問“聚集索引的正確鍵是什麼”?
答案實際上取決於您如何查詢數據。聚集索引比所有其他索引都有一個優勢:因為它總是包含所有列,所以總是覆蓋。因此,可以利用聚集索引的查詢當然不需要使用查找來滿足某些預計列和/或謂詞。
另一個難題是如何使用索引?典型的模式有以下三種:
- 探測,當在索引中搜尋單個鍵值時
- 範圍掃描,當檢索到一系列鍵值時
- 按要求排序,當索引可以滿足不需停止排序的排序時
因此,如果您分析您的預期負載(查詢)並發現大量查詢將使用特定索引,因為它們使用從索引中受益的特定訪問模式,那麼建議將該索引作為聚集索引是有意義的。
另一個因素是聚集索引鍵是所有非聚集索引使用的查找鍵,因此寬聚集索引鍵會產生連鎖反應並擴大所有非聚集索引,而寬索引意味著更多頁面、更多 I/O ,更多的記憶,更少的善良。
一個好的聚集索引是穩定的,它在實體的生命週期內不會改變,因為聚集索引鍵值的變化意味著該行必須被刪除並重新插入。
並且一個好的聚群索引不是隨機增長的(每個新插入的鍵值都大於前一個值)以避免頁面拆分和碎片(不弄亂
FILLFACTOR
s)。那麼現在我們知道什麼是好的聚集索引鍵,主鍵(它是一個數據建模邏輯屬性)是否符合要求?如果是,那麼 PK 應該是集群的。如果不是,那麼 PK 應該是非集群的。
舉個例子,考慮一個銷售事實表。每個條目都有一個作為主鍵的 ID。但是絕大多數查詢都需要一個日期和另一個日期之間的數據,因此最好的聚集索引鍵是銷售日期,而不是ID。另一個具有與主鍵不同的聚集索引的範例是選擇性非常低的鍵,例如“類別”或“狀態”,只有很少的不同值的鍵。將具有這種低選擇性鍵的聚集索引鍵作為最左邊的鍵,例如
(state, id)
,通常是有意義的,因為範圍掃描會查找特定“狀態”中的所有條目。關於堆上可能存在非聚集主鍵的最後一點說明(即根本沒有聚集索引)。這可能是一個有效的場景,典型的原因是大容量插入性能至關重要,因為與聚集索引相比,堆的大容量插入吞吐量要好得多。