Question

Faut-il utiliser un drapeau pour doux, ou supprime une table de menuisier séparée? Ce qui est plus efficace? Base de données SQL Server est.

Informations générales

A quelque temps nous avions un consultant DB venir et consulter notre schéma de base de données. Lorsque l'on supprime un disque doux, nous mettre à jour un drapeau IsDeleted sur la table appropriée (s). Il a été suggéré qu'au lieu d'utiliser un drapeau, stocker les enregistrements supprimés dans une table séparée et utiliser une jointure comme ce serait mieux. J'ai mis cette suggestion à l'épreuve, mais au moins sur la surface, la table supplémentaire et rejoindre semble être plus cher que l'aide d'un drapeau.

Essais initiaux

Je l'ai mis en place ce test.

Deux tableaux, l'exemple et DeletedExample. J'ai ajouté un index non clusterisé sur la colonne IsDeleted.

Je l'ai fait trois essais, le chargement d'un million d'enregistrements avec les éléments suivants supprimé / non délétés rapports:

  • supprimé / NonDeleted
  • 50/50
  • 10/90
  • 1/99

Résultats - 50/50 50 50

Résultats - 10/90 10 90

Résultats - 1/99 entrer image description ici

Scripts de base de données, pour référence, exemple, DeletedExample et index pour 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
Était-ce utile?

La solution

The numbers you have seem to indicate that my initial impression was correct: if your most common query against this database is to filter on IsDeleted = 0, then performance will be better with a simple bit flag, especially if you make wise use of indexes.

If you often query for deleted and undeleted data separately, then you could see a performance gain by having a table for deleted items and another for undeleted items, with identical fields. But denormalizing your data like this is rarely a good idea, as it will most often cost you far more in code maintenance costs than it will gain you in performance increases.

Autres conseils

I'm not the SQL expert but in my opinion,it all depends on the usage frequency of the database. If the database is accessed by the large number of users and needs to be efficient then usage of a seperate isDeleted table will be good. The better option would be using a flag during the production time and as a part of daily/weekly/monthly maintanace you may move all the soft deleted records to the isDeleted table and clear the production table of soft deleted records. The mixture of both option will be good a good one.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top