我有这个 M2M 连接表:
CREATE TABLE [dbo].[RecipientsDonors]
(
[RecipientId] [int] NOT NULL,
[DonorId] [int] NOT NULL,
CONSTRAINT [PK_RecipientsDonors] PRIMARY KEY CLUSTERED
(
[RecipientId] ASC,
[DonorId] ASC
)
)
我也有这两个索引:
CREATE NONCLUSTERED INDEX [IX_RecipientsDonors_RecipientId] ON [dbo].[RecipientsDonors]
(
[RecipientId] ASC
)
CREATE NONCLUSTERED INDEX [IX_RecipientsDonors_DonorId] ON [dbo].[RecipientsDonors]
(
[DonorId] ASC
)
我使用这两个索引的目的是加快单列查找速度。
既然主键存在,那么索引是否是多余的呢?或者它们是必要的,因为主键包含两列?
索引始终只能由前导键使用。因此
IX_RecipientsDonors_RecipientId
索引并不是真正必要的,因为主键已经涵盖了相同的列。虽然它会稍微提高单列扫描的性能(由于索引稍微窄一些),但这种扫描的可能性很低(如果可以查找,为什么还要扫描?),并且仅查询单列的可能性很低反正。此外,在每次插入、更新和删除时保持索引与表保持同步还存在索引成本,以及存储和备份索引的存储成本。
IX_RecipientsDonors_DonorId
然而,另一个索引应该保留。这对于对该列进行常规查找是必要的,而且因为每当删除父表行时,它将在外键查找中大量使用。但明智的做法是向其中添加另一列,以便您可以完全涵盖寻求
DonorId
但想要RecipientId
结果的查询。它也应该是唯一的,以便编译器可以推断优化。这应该是您创建的每个两列多对多联接表的正常设置:两列上都有一个主键,以及一个辅助唯一索引,其中键列的顺序相反。