Sql-Server
為多個外鍵添加多個單獨索引與一個組合索引
背景
我有一個“連接”表,用於將一個“事務”表與基於多列(並通過多個連接)的“類別”表連接起來:
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 表中附加到哪一行。