9

我们应该为软删除使用标志,还是使用单独的连接器表?哪个更有效率?数据库是 SQL Server。

背景资料

不久前,我们有一位数据库顾问进来查看我们的数据库模式。当我们软删除一条记录时,我们将更新相应表上的 IsDeleted 标志。建议不要使用标志,将删除的记录存储在单独的表中并使用连接,因为这样会更好。我已经对这个建议进行了测试,但至少从表面上看,额外的表和连接看起来比使用标志更昂贵。

初步测试

我已经设置了这个测试。

两个表,Example 和 DeletedExample。我在 IsDeleted 列上添加了一个非聚集索引。

我做了三个测试,加载了一百万条具有以下已删除/未删除比率的记录:

  • 已删除/未删除
  • 50/50
  • 10/90
  • 1/99

结果 - 50/50 50 50

结果 - 10/90 10 90

结果 - 1/99 在此处输入图像描述

数据库脚本,供参考、示例、DeletedExample 和 Example.IsDeleted 的索引

CREATE TABLE [dbo].[Example](
    [ID] [int] NOT NULL,
    [Column1] [nvarchar](50) NULL,
    [IsDeleted] [bit] NOT NULL,
 CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Example] ADD  CONSTRAINT [DF_Example_IsDeleted]  DEFAULT ((0)) FOR [IsDeleted]
GO

CREATE TABLE [dbo].[DeletedExample](
    [ID] [int] NOT NULL,
 CONSTRAINT [PK_DeletedExample] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[DeletedExample]  WITH CHECK ADD  CONSTRAINT [FK_DeletedExample_Example] FOREIGN KEY([ID])
REFERENCES [dbo].[Example] ([ID])
GO

ALTER TABLE [dbo].[DeletedExample] CHECK CONSTRAINT [FK_DeletedExample_Example]
GO

CREATE NONCLUSTERED INDEX [IX_IsDeleted] ON [dbo].[Example] 
(
    [IsDeleted] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
4

2 回答 2

11

您的数字似乎表明我最初的印象是正确的:如果您对该数据库最常见的查询是过滤IsDeleted = 0,那么使用简单的位标志性能会更好,特别是如果您明智地使用索引。

如果您经常分别查询已删除和未删除的数据,那么您可以通过使用具有相同字段的已删除项目和未删除项目的表来获得性能提升。但是像这样对数据进行非规范化很少是一个好主意,因为它通常会花费您更多的代码维护成本,而不是它为您带来的性能提升。

于 2012-01-13T21:15:20.770 回答
1

我不是 SQL 专家,但在我看来,这完全取决于数据库的使用频率。如果数据库被大量用户访问并且需要高效,那么使用单独的 isDeleted 表会很好。更好的选择是在生产期间使用标志,作为每日/每周/每月维护的一部分,您可以将所有软删除记录移动到 isDeleted 表并清除软删除记录的生产表。两种选择的混合将是一个很好的选择。

于 2012-01-13T20:32:13.767 回答