2012-02-07 72 views
2

如果我的Product表有一個CategoryId列,我知道將CategoryId設置爲聚簇索引而不是主鍵ProductId是一個好習慣。使用IN時,在非主鍵列上使用聚簇索引vs =運算符

這是否仍然適用,如果我的大部分的查詢對產品表的樣子select * from Product where CategoryId in (1, 2)而不是更典型的select * from Product where CategoryId = 1

回答

3

非常仔細挑選你的聚集索引!它非常特殊 - 每個表只能有一個,它決定了數據的物理順序,並且它用於唯一標識數據頁的位置(如果您願意的話,可以使用「行指針」)。

此外,它是最複製數據結構在您的SQL Server數據庫(假設它是你正在談論的SQL Server)。集羣密鑰將成爲表中每個非聚集索引的一部分 - 當然在葉級別中,也可能在索引導航結構中。

採摘聚集關鍵字時,您要特別小心 - 它應該是:

  • (4個字節理想)

  • 獨特(它的 「行指針」 後,所有 - 如果你沒有使它獨一無二,SQL Server會在後臺花費你幾個字節的時間 - 將行數和非聚集索引的數量乘以 - 可能會非常昂貴!)

  • 靜態(永遠不會改變 - 如果可能的話)

  • 理想不斷增加所以你不會有可怕的索引碎片落得(一個GUID是一個很好的聚集鍵的完全相反 - 爲那個特別的原因)

  • 應該非空的和最好也固定 - 一個varchar(250)使得一個非常貧窮的聚集鍵

別的真的應該是這些分落後重要的第二和第三級....

見一些金佰利特里普的(索引女王)博客上的這篇文章 - 任何她寫在她的博客絕對是無價的 - 閱讀它,消化它 - 靠它活着!

在您的具體情況,在Products桌上拿起了CategoryId聽起來並不像一個很好的主意。產品的類別可能會發生變化,這很可能不是唯一的,因此我認爲它不會真正成爲如此好的集羣密鑰。

此外,產品的類別聽起來並不像它會非常有選擇性 - 因此它甚至可能不會創建一個好的非聚簇索引。如果某個查詢返回的行數超過總行數的1-5%,則SQL查詢優化器不會使用大多數索引(因爲它們返回的數據過多)。

+0

這是我第一次讀這個問題,但我發誓我已經讀過這個完全相同的答案。你只是複製並粘貼你的答案?大聲笑。 – 2012-02-07 06:44:30

+0

偉大的答案和文章,謝謝。聚集一個獨特的密鑰是非常不直觀的 - 我將不得不再讀幾遍。 「 – kenwarner 2012-02-07 06:44:50

+0

」產品表上的CategoryId聽起來不像是一個好主意......它很可能不是唯一的「 - 我假設它們意味着按照該順序在'(CategoryId,ProductId)'**化合物上聚集索引**,這個想法是,僅當通過'CategoryId'搜索時,結果將主要在相同的物理頁面上。 – onedaywhen 2012-02-07 08:34:08

相關問題