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