Sql-Server

如果它已經是複合索引中的第一列,那麼索引它是否有用?

  • August 13, 2019

假設我有這張表(從我的項目中簡化):

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(*) 或分頁查詢可以使用這個狹窄的唯一索引,而不必掃描整個聚集索引。

但是對於上述問題,不,在沒有兩個非鍵列的情況下維護鍵索引的第二個副本不太可能有用。

引用自:https://dba.stackexchange.com/questions/245185