Jon*_*nor 8 indexing soft-delete sql-server-2008-r2
我们应该使用标志进行软删除还是单独的连接表?哪个更有效率?数据库是SQL Server.
背景资料
前一阵子,我们有一位DB顾问进来查看我们的数据库架构.当我们软删除记录时,我们将更新相应表上的IsDeleted标志.有人建议,不要使用标志,而是将已删除的记录存储在单独的表中,并使用连接,因为这样会更好.我已经把这个建议付诸实践,但至少在表面上,额外的表和连接看起来比使用标志更昂贵.
初步测试
我已经设置了这个测试.
两个表,Example和DeletedExample.我在IsDeleted列上添加了一个非聚集索引.
我做了三次测试,加载了一百万条记录,其中包含以下已删除/未删除的比率:
结果 - 50/50

结果 - 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
Run Code Online (Sandbox Code Playgroud)
您所拥有的数字似乎表明我的初始印象是正确的:如果针对此数据库的最常见查询是要过滤IsDeleted = 0,那么使用简单的位标志性能会更好,特别是如果您明智地使用索引.
如果您经常单独查询已删除和未删除的数据,则可以通过为已删除的项目设置表格来获得性能提升,而对于未删除的项目,可以看到具有相同字段的另一个表格.但是,像这样对数据进行非规范化很少是一个好主意,因为在代码维护成本方面,通常会花费更多,而不是在性能提升方面.