Sql-Server

為多個外鍵添加多個單獨索引與一個組合索引

  • October 23, 2018

背景

我有一個“連接”表,用於將一個“事務”表與基於多列(並通過多個連接)的“類別”表連接起來:

TxnTable (Entity1Name, Entity2Name, Entity3Name)

EntityTable x3(ID、名稱)

連接表(Entity1Id、Entity2Id、Entity3Id、CategoryId)

類別表(ID、名稱等)

標準查詢基本上是:

SELECT txn.*, cat.Name
FROM TxnTable txn

-- Go from transaction names to IDs
INNER JOIN Entity1 e1 ON e1.Name = txn.Entity1Name
INNER JOIN Entity2 e2 ON e2.Name = txn.Entity2Name
INNER JOIN Entity3 e3 ON e3.Name = txn.Entity3Name

-- Lookup category from join/mapping table
INNER JOIN JoinTable jt
 ON jt.Entity1Id = e1.Id
 AND jt.Entity2Id = e2.Id
 AND jt.Entity3Id = e3.Id

-- Load Category information
INNER JOIN CategoryTable cat ON cat.Id = jt.CategoryId

問題

在為“Join”表設計用於性能目的的索引時,我是否應該創建四個單獨的索引:

CREATE INDEX IX_1 ON JoinTable (Entity1Id)
CREATE INDEX IX_2 ON JoinTable (Entity2Id)
CREATE INDEX IX_3 ON JoinTable (Entity3Id)
CREATE INDEX IX_4 ON JoinTable (CategoryId)

或一個組合索引

CREATE INDEX IX_Combined ON JoinTable (Entity1Id, Entity2Id, Entity3Id, CategoryId)

或其他一些組合?

根據您的範例查詢,您需要一個組合索引,

推理:

儘管一條 Txn 記錄連接到三個不同的 Entity# 表,但一旦這些連接完成,為了提高效率,可以將其視為包含所有 Txn 數據 + Entity#ID 的單個記錄。如果您有一條包含該數據的記錄,您可能希望在一個索引而不是三個單獨的索引上進行連接,以在連接表中查找您正在查找的行。同樣的效率論點也適用於此。

將 CategoryId 作為 Join 表索引的一部分是可選的,但是對於 Category 表的下一個 join 更有效,因為它只關心數據 CategoryId,而不關心它在 Join 表中附加到哪一行。

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