3

假設我在(RetailerID, PurchaseDate, UserID)上聚簇一個表。這是「集羣密鑰」,集羣密鑰始終包含在所有非集羣索引中。 https://stackoverflow.com/a/23057196/88409 https://stackoverflow.com/a/2747869/88409將「包含」列包含在已經屬於集羣密鑰的非聚集索引中的效果如何?

接下來,我創建了一個非聚集索引「StorePurchasesIndex」鍵上(RetailerID, StoreID, PurchaseDate)進行查詢,其中包括剛剛特定商店較快的子集。

第一個問題是,我是否需要明確包含UserID作爲包含列,還是會因爲包含它的集羣密鑰而隱式地包含它?我敢肯定,在這種情況下,我不需要明確包含UserID,但如果我錯了,請糾正我。

我真的很感興趣知道的是,如果我明確包含UserID作爲包含列,會發生什麼情況。它是否會被冗餘地包含在索引中,一次作爲集羣密鑰的一部分,再次作爲包含列?還是SQL Server能夠識別這個意圖,並避免將它存儲兩次,因爲它已經通過集羣密鑰包含在內了?

第二個問題是,如果它沒有被包括在內,那麼顯式包含它是否有好處。例如,即使羣集密鑰以排除UserID並重建索引的方式進行更改,它是否會確保將來包含UserID

+1

聚類關鍵列被包含在每個非聚集索引的**葉級**處,這意味着數據在那裏,一旦找到非聚集索引值 - 但它不在索引樹中,所以它不能用於搜索/過濾。並且SQL Server足夠聰明,可以避免再次添加已經是索引葉級別一部分的列 - 因此,在您的情況下,添加集羣鍵列是毫無意義和多餘的。 –

+0

是的,但是使用包含的列定義索引確保即使它從聚簇鍵中消失,它仍然保留在索引中,對嗎? – Triynko

回答

1

對於一個非聚集索引,索引鍵/鍵出現在默認情況下,根和葉級..

此默認情況下,通過您的非聚集索引的定義不同..

當你創建一個非唯一聚簇索引,SQL Server將在根目錄添加聚簇關鍵字以使其唯一,並且它也將以葉級別存在。

當您創建唯一聚簇索引時,SQL Server將不包含聚簇關鍵字在根級,但將包括在葉級..

所以來你的問題..

第一個問題,我需要明確包括用戶名作爲包含列,也將憑藉聚集鍵,包括它的是有含蓄?

是的,你是對的,你不需要添加用戶ID中包含列表..

什麼我知道在真正感興趣的是,如果我不明確包括用戶ID爲包括會發生什麼柱。它是否會被冗餘地包含在索引中,一次作爲集羣密鑰的一部分,再次作爲包含列?還是SQL Server能夠識別這個意圖,並避免將它存儲兩次,因爲它已經通過集羣密鑰包含在內了?

SQL Server是足夠聰明,忽略這個..

第二個問題是,如果它不包括多餘的,那麼有沒有到包括它明確地受益。

即使你添加SQL Server將忽略列

例如,將它確保用戶名包含在未來,即使以這樣的方式聚集鍵的變化,這不包括用戶名和索引是否重建?

你不能改變聚集鍵定義,您必須刪除並重新創建它,所以聚集鍵發生變化時,非聚集索引重建作爲按照其定義,因此用戶ID將出席