2009-02-22 124 views
3

據我所知,SQL Server 2008將只允許每個表的一個聚集索引。爲了這個問題,我們假設我有一個包含以下列的用戶提交故事列表。在哪裏放置主鍵

ID(INT,主鍵)
標題(nvarchar的)
地址(nvarchar的)
UniqueName(nvarchar的)這是URL蛞蝓(誇誇其談-等等)
類別ID(INT,FK類別表)

大多數時間故事永遠不會被ID查詢。大多數查詢將由CategoryID或UniqueName完成。

我是新來的索引,所以我認爲最好在這個表上放置2個非聚集索引。一個在UniqueName上,一個在CategoryID上。在對索引進行一些閱讀之後,看起來好像在UniqueName上有一個聚集索引是非常有益的。考慮到UniqueName是...獨特的,將主鍵放在UniuqeName並擺脫ID字段是否有利?至於CategoryID,我假設一個非聚集索引會做得很好。

謝謝。

回答

3

首先,您可以將聚簇索引放在唯一的名稱上,它不必位於ID字段上。如果你很少或根本沒有加入這張桌子,你可以擺脫這個ID。在任何情況下,我都會在唯一的名稱字段上添加一個唯一的索引(您可能會發現它不像您認爲的那樣獨特!)。

如果你做了很多加入,但我會保持ID字段,它是更小,更有效的加入。

既然你說你是索引編制的新手,我會指出,雖然主鍵在定義時會自動創建索引,但外鍵不會。你幾乎總是想索引你的外鍵字段。

+0

我不知道你可以拆分PK和聚簇索引,非常感謝。 – 2009-02-22 19:02:18

+0

聚集索引是主鍵的默認值,但您不必這樣做。 – HLGEM 2009-02-22 19:27:32

1

出於習慣,我總是創建一個身份字段「ID」,就像您擁有PK一樣。它使事情保持一致。如果所有的「主」表都有一個名爲「ID」的字段是INT標識,那麼PK總是很明顯。另外,如果我需要創建一個橋實體,我將存儲兩個(或更多)INT類型的列,而不是類型爲nvarchar()。因此,在您的示例中,我會保留ID作爲PK,並在UniqueName上創建唯一索引。

1

數據按聚簇鍵的順序存儲;如果您要通過這些字段之一來鍵入數據的恢復,那麼假設值不會顯着分散,這可能會降低插入性能。另一方面,如果這張表加入了很多ID,那麼在PK上保留羣集密鑰可能更有意義。

1

根本沒有要求或必須有聚集索引,主鍵或其他。這是一個性能優化工具,與所有索引策略一樣,應該在使用它時獲得改進時應用。如上所述,由於表根據聚集索引鍵進行物理排序,因此這是一個漢蘭達情況:只能有一個!

聚集索引是如情況下最有用:

  • 您經常需要檢索一組行,其給定列的值是一個範圍,所以列是經常的的主題條款很有趣;或
  • 表中的大部分單行命中都出現在可由鍵的值的子集描述的區域中。

我認爲他們是特別沒有用的情況下,例如當您的大量事務處理系統頻繁插入時,順序鍵是聚集列。你會得到一組試圖插入同一個物理位置(一個「熱點」)的進程。結果,正如在此編輯之前所評論的那樣,我很傷心地過時並顯示我的年齡。請參閱this post on the topic by Kimberley Tripp其中說這一切都好多了。

序列數字「ID」列通常不是很好的候選列。如果仔細考慮,名稱可以很好,日期也是如此。

+0

如果你相信金佰利Tripp,以及爲什麼任何人不相信她:-),熱點現象在行鎖定之前是相關的。現在,在同一個地方做更新實際上是有益的,因爲緩存。 – 2009-02-23 03:37:16

1

通常,最好在身份密鑰上索引表並將其用作聚集索引。有一個簡單的經驗法則在這裏

不要使用有意義的列作爲主索引

這樣做的原因是,一般使用上一個有意義的列中的PK往往會引起維護問題。這是一條經驗法則,因此可以被這種情況所規定,但通常最好從假設的每個表的默認位置開始工作,該位置由一個(聚集的)無意義的標識列索引。這樣對連接更加高效,而且由於它通常是大多數數據庫管理員採用的默認設計,所以不會引起任何問題,也不會提出任何問題,因爲它們的系統不像下一個DBA可能承擔的那樣。無意義的PK總是更靈活,並且可以更容易地適應不斷變化的環境,否則

何時重寫規則?只有在你設想性能問題的時候。對於大多數在現代硬件上合理加載適當索引的數據庫,如果不通過對最佳索引進行聚類來壓縮最後一毫秒的性能,那麼您將不會遇到任何問題。數據庫管理員和程序員的週期比CPU週期要貴得多,如果你只通過採用不同的策略來減少奇怪的毫秒數,那麼它就不值得。但是,如果你正在看一張接近一百萬行的桌子,那麼這是另一回事。這很大程度上取決於環境,但通常如果我設計的表的行數少於100,000行,我將傾向於設計靈活性,易於編寫穩定的查詢,以及任何其他設計人員期望看到的主體。超過一百萬行,然後我設計性能。在10萬到100萬之間,這是一個判斷問題。