2013-06-21 63 views
1

假設我有這樣一張桌子。 Id是主鍵,所以我知道我得到了一個索引。表的主鍵是該表的另一個索引中的列嗎?

CREATE TABLE Employer 
(
    Id VARCHAR(64) NOT NULL, 
    EntityId VARCHAR(64) NOT NULL, 
    Name VARCHAR(64) NOT NULL, 
    Address1 VARCHAR(64) NOT NULL, 
    Address2 VARCHAR(64) NOT NULL, 
    City VARCHAR(64) NOT NULL, 
    JobTitle VARCHAR(64) NOT NULL, 
    StateCode VARCHAR(64) NOT NULL, 
    ZipCode VARCHAR(64) NOT NULL, 
    CONSTRAINT PK_Employer_Id PRIMARY KEY CLUSTERED (Id ASC) 
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
) 

比方說,我添加了另一個索引來幫助一些特殊的搜索(雖然之所以沒有真正相關的原因)。是否有理由將Id(主鍵)包含爲索引中的一列?我有SQL專家告訴我這是浪費空間,因爲索引將以某種方式包含主鍵。

CREATE INDEX [idxEmployerByNameAddress1City] on [Employer] ([EntityId], [Id], [Name], [Address1], [City]) 
+2

**請使用** - 請勿將'VARCHAR(64)'作爲聚簇索引!這對性能來說真的是非常糟糕...... SQL Server表上的聚簇索引應該很小(4-8字節)和固定寬度(不是可變寬度,比如'VARCHAR(64)') - INT IDENTITY'幾乎完美。閱讀[Kimberly Tripp的不斷增長的集羣密鑰 - 聚集索引辯論.........。關鍵!](http://www.sqlskills.com/blogs/kimberly/ever-increasing-clustering-key-the-clustered-index-辯論 - 再次/)博客文章和她在聚集索引上發佈的任何內容 - 她是* SQL Server索引*的女王* - 遵循她的建議! –

+1

您的羣集密鑰(默認情況下是主鍵)將自動成爲每個非聚集索引的一部分 - 這也是集羣密鑰應該很小且性能良好的另一個原因!但是,單獨添加'ID'不是浪費空間 - 無論如何它都包含在該索引中,如果您明確指定它,SQL Serve將不會複製它 - >沒有空間被浪費。 –

+0

我同意VARCHAR(64)的東西。對於我們的應用來說,這是一個遺留問題,實際上它有一個半好的理由。所以現在很難改變。但在我們的應用程序的下一個版本中,我們計劃切換到大型整數或指導。 –

回答

0

如果您的二級索引不與主鍵列(多個)啓動,則主鍵是不相干的二級索引。另一方面,如果你的索引根據前兩列是唯一的,因爲它看起來可能就是這種情況,那麼在密鑰中有更多列是沒有意義的 - 這隻會浪費空間指數。

+0

空間浪費的好處。把它們移到INCLUDE子句是否有意義?這些列是查詢的SELECT列表的一部分,這個索引是我相信的。 –

0

索引用於各種目的。其中之一是滿足只使用索引中的列的查詢。所以,如果你有這樣的查詢:

select col, max(pk) 
from t 
group by col 

而且你t(col)有一個索引,那麼查詢必須從數據頁取的pk值。如果主鍵位於索引中,則原始數據頁面不是必需的。

因此,有些情況下在索引中包含主鍵是個好主意。

順便說一下,我完全同意主鍵不應該是varchar(64)的評論。我鼓勵你使用整數主鍵,使用identity()。而且,出於某種原因,我認爲擁有可變長度的主鍵是一個糟糕的主意 - 可能是因爲'A'' A'之間的混淆 - 它們有所不同,但打印輸出時可能看起來不一樣。

我會進一步說明,如果主鍵存儲在其他表中,那麼索引中浪費空間的問題就沒有意義了。你正在浪費太多的空間來存儲這麼大的主鍵,這樣在索引中浪費多一點並不是什麼大問題。

相關問題