2012-01-13 15 views
8

Yumuşak silme veya ayrı bir marangoz tablosu için bayrak kullanmalı mıyız? Hangisi daha verimli? Veritabanı SQL Server'dır.Soft Sil - IsDeleted bayrağı veya ayrı bir marangoz tablasını kullanın?

Temel Bilgiler

Bir süre önce bir DB danışman gelip bizim veritabanı şemasına bakabilirsiniz vardı. Bir kaydı sildiğimizde, uygun tablodaki bir IsDeleted işaretini güncellerdik. Bir bayrak kullanmak yerine, silinmiş kayıtları ayrı bir tabloda saklayın ve daha iyi olacak şekilde bir birleştirme kullanın. Bu öneriyi teste tabi tuttum, ama en azından yüzeyde, ekstra masa ve birleştirme daha sonra bir bayrak kullanarak daha pahalı görünüyor.

Ben bu testi kurdum

Başlangıç ​​Testi.

İki tablo, Örnek ve Silinmiş Örnek. IsDeleted sütununda kümelenmemiş bir dizin ekledim.

yaptım şu silinen/olmayan silinmiş oranlarına sahip bir milyon kayıtları yüklenirken üç testleri,:

  • Silinmiş/delesyona
  • 50/50
  • 10/90
  • 1/99

Sonuçları - 50/50 50 50

Sonuçları - 10/90 10 90

Sonuçları - Example.IsDeleted için Referans Örnek, DeletedExample ve Index için 1/99 enter image description here

Veritabanı Script,

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 

cevap

8

my initial impression numaralı telefonun doğru olduğunu belirttiğiniz numaralar: bu veritabanına en sık sorulan sorgunuz IsDeleted = 0 filtrelemeye dayanıyorsa, özellikle endeksleri akıllıca kullanırsanız, basit bir bit işareti ile performans daha iyi olacaktır.

Silinmiş ve silme işlemine tabi tutulmuş olan verileri ayrı ayrı sorguladığınızda, silinen öğeler için bir tablo ve silinen öğeler için diğeriyle aynı alanları içeren bir performans artışı görebilirsiniz. Ancak, verilerinizi bu şekilde denormalize etmek, nadiren iyi bir fikirdir, çünkü performans artışlarında size kazanç sağlayacağından, çoğu kez kod bakım maliyetlerinde size çok daha pahalıya mal olacaktır.

+2

İyi yanıt. Ayrıca filtre uygulanmış dizinleri kullanmayı düşünün.Kayıtlar silinmediğinde yalnızca Örnek tablosunu Column1 ile sorgularsanız, Column1 "WHERE IsDelete = 0" dizinini. –

1

ben SQL uzmanı değilim ama bence her şey veri tabanının kullanım sıklığına bağlı. Veritabanına çok sayıda kullanıcı tarafından erişilebiliyorsa ve verimli olması gerekiyorsa, ayrı bir isDeleted tablosunun kullanılması iyi olacaktır. Daha iyi bir seçenek, üretim süresi boyunca bir bayrak kullanacak ve günlük/haftalık/aylık bakımın bir parçası olarak, tüm silinmiş kayıtları isDeleted tablosuna taşıyabilir ve yumuşak silinen kayıtların üretim tablosunu temizleyebilirsiniz. Her iki seçeneğin karışımı iyi olacak.