如果它已經是複合索引中的第一列,那麼索引它是否有用?
假設我有這張表(從我的項目中簡化):
create table BillTax ( BillID int not null constraint FK_BillTax_Bill foreign key references Bill(BillID), TaxCode varchar(20) not null, constraint PK_BillTax primary key clustered (BillID, TaxCode), TaxRate decimal (10, 9) not null, TaxAmount decimal (12, 4) not null, );
如您所見,主鍵是 BillID 和 TaxCode 列的組合,並使用聚集索引來提高速度。針對該表的所有查詢都將在 BillID 上查找,但某些查詢將同時在 BillID 和 TaxCode 上查找。此外,所有查詢都將包括其他列(例如,TaxRate、TaxAmount)作為結果數據。鑑於這些查詢,僅在 BillID 列上創建一個單獨的(非聚集的)索引是否有用?
缺點:
- 浪費空間
- 增加了複雜性
- 插入性能下降
優點:
- 單個列上的索引應該非常小
- 查詢優化器應該能夠以任何一種方式選擇最佳查詢(但我們知道查詢優化器並不總是像我們想要的那樣聰明)
我的理解是,如果我僅在 BillID 列上查詢此表,查詢優化器仍將使用聚集索引,因為該索引將 BillID 列作為其第一列。而且它會非常快,因為即使索引會更大一些,因為它包含了 TaxCode 列,但集群將彌補這一點。另一方面,有人可能會爭辯說,如果返回的數據不是那麼重,單個非聚集索引可能會更快。請參閱非聚集索引比聚集索引快?對於一個相關的問題。
我知道,我知道,嘗試兩者並自己測量。我想我只是想知道我是否遺漏了一個主要的理論考慮因素,從而使一種方法或另一種方法沒有實際意義。
注意:我在這裡發現了一個可能的重複項,但它專門針對 PostgreSQL,並且接受的答案依賴於一些特定於 DBMS 的實現細節,例如數據類型儲存大小: 複合索引是否也適用於第一個欄位的查詢?(原文如此)。
鑑於這些查詢,僅在 BillID 列上創建一個單獨的(非聚集的)索引是否有用?
首先,請注意 BillId 上的索引將包括 TaxCode。聚集索引鍵是該表的行定位符,因此每個索引都必須包含它。並且對於非唯一索引,將聚集索引鍵列添加為索引鍵列,以使索引在物理上唯一。
它只是不包括葉子頁面上的其餘列。這樣的索引有時很有用,尤其是當您有一個寬表而沒有其他索引時。
例如,一個 COUNT(*) 或分頁查詢可以使用這個狹窄的唯一索引,而不必掃描整個聚集索引。
但是對於上述問題,不,在沒有兩個非鍵列的情況下維護鍵索引的第二個副本不太可能有用。