2016-09-14 120 views
1

我一直在嘗試閱讀使用聚簇索引作爲提高查詢性能的手段。非唯一列上的SQL Server聚簇索引

本質上,我有一個'消息'表,用於聊天應用程序。當用戶打開聊天時,我們根據用戶正在說話的客戶從表格中讀取消息歷史記錄。

消息表的結構與列:

編號:客戶編號:內容

經常在桌子上使用的查詢將會像

SELECT * FROM Message WHERE CustomerId = @CustomerId 

我的問題是,CustomerId列是聚集索引的合適候選者嗎?另外,鑑於ID字段是主鍵,SQL Server是否仍然需要「唯一化」聚集索引?

這個表格在選擇和插入時都很重。

回答

1

聚集索引不需要是唯一的,所以它是可能的。

但是,問題是每次插入新消息時,SQL Server都需要爲同一個客戶找到其他行旁邊新行的空間。這通常效率不高,因爲頁面需要分割,導致許多半滿頁面。而且,如果你也刪除了行,事情會變得更加複雜。

有幾種選擇。在繁忙的數據庫中,您可以在頁面上留出空間以獲取更多插入內容。或者,另一種選擇是根據客戶ID對錶格進行分區。這完全取決於。

在大多數情況下,郵件表上的標識列也是主鍵和集羣鍵。客戶表上的額外索引就足夠了。但是,在某些情況下,確實存在可以更好地工作的替代結構。

0

在已經存在主鍵約束的鍵上添加聚簇索引是不必要的重複。相反,主鍵約束也應該是聚集索引。然而,你的問題其實是不同的...

是CustomerId列適合聚集索引的候選人嗎?

如果不知道,你將如何回答這個問題。有許多查詢模式,這個組織將而不是是最優的(典型例子是時間序列,其中時間列是適當的集羣密鑰)。而且這個最好的聚集索引。無法回答。

假設ID字段是主鍵,SQL Server是否仍然需要'唯一化'聚集索引?

如果指數不聲明唯一那麼SQL Server將添加唯一標誌列。儘管如此,的值永遠不會實現,因爲不會有重複發生。

我有一個「消息」表,這是在一個聊天應用程序... WHERE CustomerId = @Id使用... ID字段是主鍵

對不起,但這不作任何感。你所說的是,Messages只能從每個客戶只有一條消息。那會造成可怕的聊天體驗。我很確定你的解釋是錯誤的。

我期望Customers表聚合索引和主鍵約束CustomerId。該Messages表很可能是由聊天室,或其他一些團體組織,對聊天參與者來組織。如果在一個客戶和一個代表之間的聊天內容爲總是,那麼'聊天室'可能就是客戶本身。無論如何,這種Messages表的典型查詢將想要所有在聊天室中交換的消息,所發佈的訂單發佈所有與客戶交換的消息,發佈順序爲。實際上,這是一個分區時間序列,最適合聚集索引,如(chat_id, post_time)(customer_id, post_time)。請注意,這不是主鍵,該表可能有message_id作爲主鍵,但非集羣。

+0

@GordonLinoff使一個有效的點,像'一個聚集鍵(chat_id,post_time)'因爲數據被插入在指數多點導致了分裂,但在我的經驗,當* *它成爲一個問題,就是可以通過簡單的重組來解決,或重建(最終使用低fill_factor)。選擇一個聚集索引來確保物理組織的僅附加語義,並懲罰過程中的查詢通常會更糟糕。 –

+0

'@Id'應該是作爲傳入存儲過程的參數的客戶ID。所以,你會通過他們的Id查找所有消息給客戶。這是一個寫得不好的例子。是的,在這種情況下,'客戶ID'基本上是聊天室標識符。 –