Warum verdreifacht sich meine SQL Server-Datenbank nach dem Löschen von Millionen von Datensätzen?

7

Wir haben zwei Datenbanktabellen ErrorLogund Auditdie beide ziemlich groß in den letzten Jahren gewachsen. Um die Größe der Datenbank zu verringern, muss ich ein Skript schreiben, um alle Zeilen, die älter als 6 Monate sind, aus diesen beiden Tabellen zu entfernen.

Das habe ich mir ausgedacht:

ALTER DATABASE StudioWebTest SET RECOVERY SIMPLE;

DELETE FROM [Audit] WHERE AuditDate < DATEADD(M, -6, GETDATE());
DELETE FROM [ErrorLog] WHERE ErrorDate < DATEADD(M, -6, GETDATE());

ALTER DATABASE StudioWebTest SET RECOVERY FULL;

Auf meinem Entwicklungscomputer (SQL Server 2008 R2) mit oder ohne Änderung des Wiederherstellungsmodus vergrößert sich die Datenbankgröße um das 2-3-fache. Wenn ich dem jedoch sofort einen Verkleinerungsbefehl hinzufüge, wird die Größe der Datenbank auf die Hälfte der ursprünglichen Größe reduziert (vor dem Löschen des Datensatzes).

Wenn ich mich jedoch einige Tage mit dem Verkleinern zurückhalte, ist das Verkleinern nicht annähernd so effektiv, da die Datenbankgröße zwar reduziert wird, aber immer noch fast doppelt so groß ist wie vor dem Löschen der Datensätze. Da ich nicht zu viel darüber weiß, wie SQL Server den zugewiesenen Speicherplatz verwendet, gehe ich davon aus, dass dies etwas damit zu tun hat, dass der zusätzliche Speicherplatz verwendet wird, der freigegeben wurde.

Das wäre alles in Ordnung, bis auf eine Sache. Wenn wir dies in unserer Produktionstestumgebung ausführen, die SQL Server 2005 verwendet, reduziert der Befehl shrink die Größe der Datenbank nicht auf die Hälfte ihrer ursprünglichen Größe.

Als Alternative habe ich auch versucht, TRUNCATEanstelle von zu verwenden, DELETEaber dies scheint keinen großen Unterschied zu machen. Die Datenbank wächst nach Abschluss der Anweisungen immer noch massiv und ich muss sie immer noch verkleinern, um das gleiche Ergebnis zu erzielen. Wir haben dies noch nicht auf der Produktionstestmaschine versucht, aber da der Schrumpfungsbefehl es nicht zu schneiden scheint, scheint es zweifelhaft, dass dies zu einer Verbesserung führt.

Wie auch immer, ich habe mich nur gefragt, ob jemand erklären kann, warum die Datenbank trotz Änderung der Fehlerbehebungseinstellung so stark wächst. Wie kann dies verhindert werden? Oder schlagen Sie möglicherweise ein alternatives Mittel vor, um die Größe der Datenbank zu verringern, wenn dies nicht der beste Weg ist, dies zu tun.

AKTUALISIEREN:

Ich habe nur noch ein paar Tests damit gemacht, TRUNCATEes scheint jetzt nicht größer zu werden (vielleicht habe ich es mir vorgestellt). Ich muss die Datenbank immer noch verkleinern, um eine Verringerung der Gesamtgröße zu sehen. Ich könnte dies auf dem Produktionstestserver versuchen. Letztendlich denke ich, dass meine Manager glücklich sein werden, solange die Größe bis zu einem gewissen Grad abnimmt.

Entwickler
quelle
2
Wie messen Sie "die Datenbankgröße"? Beziehen Sie das Protokoll in Ihre Berechnungen ein?
Aaron Bertrand
Ich erhalte die Größe aus den Datenbankeigenschaften.
Entwickler
Sichern Sie Ihre Transaktionsprotokolle? Nicht Ihre Datenbank - Ihre Protokolle?
HLGEM

Antworten:

12

Sie führen zwei riesige Löschvorgänge durch, die jeweils innerhalb einer impliziten Transaktion erfolgen. Jeder gelöschte Datensatz wird zuerst in das Transaktionsprotokoll geschrieben.

Da Sie die Datenbank so geändert haben, dass sie sich im einfachen Modus befindet, wird das Transaktionsprotokoll am Prüfpunkt abgeschnitten, aber Sie bewirken immer noch, dass es bei jeder Löschanweisung wächst.

Ich schlage vor, Sie teilen die Löschungen in Stücke. Innerhalb einer Schleife können Sie einen Tag nach dem anderen löschen, beginnend mit den ältesten Daten, bis zur 6-Monats-Marke. (Stellen Sie sicher, dass Sie über Indizes verfügen, die Ihre Löschkriterien unterstützen, erstellen Sie sie gegebenenfalls und löschen Sie sie anschließend.)

Auf diese Weise treten die Prüfpunkte häufiger auf, wodurch die Größe des Transaktionsprotokolls auf ein Minimum reduziert wird.

Durch das Abschneiden einer Tabelle wird die Datenbank NICHT vergrößert.

Stellen Sie außerdem vor dem Ausgeben der delete-Anweisungen sicher, dass Sie herausfinden, ob in dieser Tabelle Trigger vorhanden sind.

Datagod
quelle
1
Das Gleiche gilt für die Dosierung.
jl01
Ich werde es versuchen.
Entwickler