2010-10-03 54 views
2

想從這裏得到一些建議。我得到了一張表,我想跟蹤一個對象以及與該對象相關的鍵列表。例如:SQL Server - 字典的聚集索引設計

OBJECTID ITEMTYPE ITEMKEY 
-------- -------- ------- 
1   1   THE 
1   1   BROWN 
1   2   APPLE 
1   3   ORANGE 
2   2   WINDOW 

兩個OBJECTID和的ItemKey具有高選擇性(即,OBJECTID和的ItemKey非常多樣)。我的訪問有兩種方法:

  • 通過OBJECTID:每次對象的變化,主要變化的列表中,這樣的關鍵是基於OBJECTID需要。變化頻繁發生。

  • 按ITEMKEY:這是關鍵字搜索,也經常發生。

所以我可能需要兩個密鑰,並選擇一個聚集索引(也就是更頻繁訪問的一個,或者我想要的速度來定,現在讓我們假設我將優先OBJECTID爲羣集)。我感到困惑的是我應該如何設計它。

我的問題是,這是更好的:

一)集羣(OBJECTID,ITEMTYPE,的ItemKey)的指數,再(的ItemKey的指數)。我擔心的是,由於聚簇索引非常大(2個整數,1個字符串),索引會很大,因爲所有索引項都必須指向聚簇鍵。 b)創建一個具有正在運行的標識DIRECTORYID(integer)作爲主鍵和聚集索引的新列,併爲(OBJECTID,ITEMTYPE,ITEMKEY)和(ITEMKEY)聲明兩個索引。這將最小化索引空間,但具有更高的查找成本。

c)(OBJECTID,ITEMTYPE,ITEMKEY)的集羣索引和它上面的(ITEMKEY,ITEMTYPE,OBJECTID)的物化視圖。我的邏輯是,這樣可以避免重要查找,並且仍然會像查找a)中的索引一樣大,代價是更高的開銷。

d)錯誤......也許有更好的方法給出的要求?

由於提前, 安德魯

+0

爲什麼你認爲你只需要在'(OBJECTID,ITEMTYPE,ITEMKEY)'而不是'(OBJECTID)'上集羣呢? – Lucero 2010-10-03 08:18:01

+0

如果您嘗試在SQL Server中構建高性能關鍵字搜索,則應考慮全文搜索:http://msdn.microsoft.com/en-us/library/ms142583.aspx – 2010-10-03 08:23:11

+1

@Lucero:clustering鍵必須是唯一的 - 而ObjectId則不是。在這種情況下,SQL Server將向您的索引條目添加一個4字節的唯一標識符 - 您可以通過爲您的集羣標識符選擇一個真正唯一的列(INT標識符)來避免這種情況。 – 2010-10-03 08:30:02

回答

1

如果有可能,儘量保持你的聚集鍵儘可能小,因爲它也將被添加到上表中的所有非聚集索引。

因此,如果有可能,我會使用INT,或者可能是兩個INT的組合 - 但絕對不會是VARCHAR列 - 尤其是如果該列可能寬(> 10個字符)並且必然會更改。

所以你提出的選擇,我個人會選擇b) - 爲什麼?

添加替代DirectoryID將滿足所有的關鍵標準,聚集關鍵字:

  • 穩定
  • 獨特
  • 不斷增加

和你的其他非聚集指數將受到最小影響。

請參閱Kimberly Tripp的outstanding blog post關於在您的SQL Server表上選擇一個好的集羣密鑰的主要標準 - 非常有用和有啓發性!

爲了滿足您的查詢要求,我會添加兩個非聚集索引,一個在ObjectID(可能包括其他頻繁需要的列),另一個在ItemKey上按鍵名搜索。

+0

感謝您指出帖子,它很有啓發性(嘗試按照最常用的方式進行聚類似乎更直觀,但從文章看來,似乎給出了真實世界的情況,還有其他開銷會讓其更好地跟隨這些關於集羣密鑰的規則!) – andrwo 2010-10-04 08:01:38

+0

marc_s:我對您的意見有個疑問:使用(OBJECTID,DirectoryID)作爲集羣密鑰會有意義嗎?這樣做至少可以使它按照一個標準進行聚類,同時保持聚類關鍵點小(但會在表格屬性結尾處始終丟失插入)。這是否值得,你會在你的設計中做到這一點嗎? – andrwo 2010-10-04 08:25:56

+0

@andrwo:如果DirectoryID是一個INT IDENTITY列,那麼我只會聚集在這個單一的INT上 - 沒有意義的是在集羣索引中增加第二個INT,或者你爲什麼要這樣做? – 2010-10-04 11:31:10