Czy powinniśmy używać flagi do miękkich operacji usuwania lub oddzielnego stołu stolarskiego? Który jest bardziej wydajny? Baza danych to SQL Server.Soft Delete - Użyj flagi IsDeleted lub oddzielnego stołu stolarskiego?
Informacja Tło
Jakiś czas temu mieliśmy konsultant DB przyjść i spojrzeć na nasze schematu bazy danych. Po miękkim usunięciu rekordu zaktualizujemy flagę IsDeleted na odpowiednich tabelach. Zasugerowano, że zamiast używać flagi, przechowuj usunięte rekordy w osobnej tabeli i korzystaj z łączenia, bo byłoby lepiej. Poddałem tę sugestię testowi, ale przynajmniej na pozór dodatkowy stół i łączenie wyglądają na droższe niż używanie flagi.
Wstępne badanie
mam skonfigurować ten test.
Dwie tabele, przykłady i usunięte przykłady. Dodałem nieklastrowany indeks do kolumny IsDeleted.
Zrobiłam trzy testy, ładowanie milionów płyt z następującymi usunięte/non usuniętych proporcjach:
- usunięte/NonDeleted
- 50/50
- 10/90
- 1/99
Wyniki - 50/50
Wyniki - 10/90
Wyniki - 1/99
skryptów bazy danych, w celach informacyjnych, przykładowo DeletedExample i indeks dla 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
Dobra odpowiedź. Rozważ także użycie filtrowanych indeksów.Jeśli zapytanie dotyczy tabeli Przykład tylko w kolumnie 1, gdy rekordy nie zostaną usunięte, indeks Kolumna1 "WHERE IsDelete = 0". –