Neuerstellung von Indizes, DB jetzt 10x so groß

13

Ich habe eine SQL Server-Datenbank (2008 R2 SP1), die etwa 15 Gigs betrug. Es stellte sich heraus, dass die Wartung schon seit einiger Zeit nicht mehr ausgeführt wurde. Deshalb habe ich einen Wartungsplan erstellt, um alle Indizes neu zu erstellen. Sie waren sehr fragmentiert.

Der Job ist beendet und die Fragmentierung ist weg, aber jetzt ist die Datenbank über 120 Gigs! Ich verstehe, dass es zusätzlichen Speicherplatz für alle Neuerstellungen verwendet hätte, aber jetzt, wo die Arbeit erledigt ist, würde ich annehmen, dass dieser Speicherplatz freier Speicherplatz ist, aber der freie Speicherplatz wird nur als 3 Gigs angezeigt, sodass 117 Gigs verwendet werden obwohl der Index-Neuerstellungsjob beendet ist.

Ich bin sehr verwirrt und könnte eine Anleitung gebrauchen. Ich habe die Datenbank wieder auf eine vernünftige Größe gebracht. Wir haben nicht den Speicherplatz dafür.

Danke im Voraus!

Hier sind die Ergebnisse der beiden Abfragen:

log_reuse_wait_desc NICHTS

name    TotalSpaceInMB  UsedSpaceInMB   FreeSpaceInMB
LIVE_Data   152             123             28
LIVE_Log    18939           89              18849
LIVE_1_Data 114977          111289          3688

Die dritte Datei ist eine .ndf-Datei, die nur 3688 im nicht genutzten Speicherbereich anzeigt, aber 111289 für etwa 15 Gigs Daten.

AS2012
quelle

Antworten:

15

In der Zwischenzeit habe ich das gerade herausgefunden, totales Aufstoßen des Gehirns. Ich hatte angegeben, was ich dachte, war ein Füllfaktor von 90 im Wiederherstellungsjob, aber es heißt "Ändere den Prozentsatz des freien Speicherplatzes in", also verwendete ich mit einem Wert von 90 tatsächlich einen Füllfaktor von 10 !! DOH. Kein Wunder, dass es zehnmal so groß wurde. Ich werde mit dem richtigen Füllfaktor wieder aufbauen und dann schrumpfen. Vielen Dank an alle für den Input.

AS2012
quelle
1
Dieser Zauberer ist einfach schrecklich.
USR
Ich weiß, ich bin es so gewohnt, auf der Kommandozeile FILL_FACTOR und nicht free% anzugeben, ich wünschte, es wäre konsistent.
Nicht neu indizieren, dann schrumpfen, es ist nur Zeitverschwendung! Siehe meine Antwort für weitere Informationen.
JNK
1
JNK Ich weiß, was Sie damit meinen, schrumpfen Sie nach einem Neuaufbau nicht, da dies alles wieder fragmentieren wird. In diesem speziellen Szenario, in dem Jeff versehentlich 90% freien Speicherplatz zu jeder Seite hinzugefügt hat, sehe ich keine andere Möglichkeit, den Speicherplatz zurückzugewinnen, als: mit fillfactor 90 neu zu erstellen, Datei zu verkleinern, jedoch müssten Sie einen weiteren Neuaufbau durchführen wieder mit Füllfaktor 90%. Oder gäbe es eine andere Möglichkeit, den Platz zurückzugewinnen. (Nun, vielleicht eine neue Dateigruppe und dann mit Drop auf die neue Dateigruppe neu erstellen, aber das funktioniert nicht für alle)
Edward Dortland
2

Das Neuerstellen von Indizes verursacht zusätzlichen Speicherplatz in der Datenbank. Dies ist ein natürliches Nebenprodukt des Neuindizierungsprozesses. Der Server erstellt neben der aktuellen Version eine neue, hoffentlich zusammenhängende Version des Index und löscht die aktuelle Version, wenn sie abgeschlossen ist.

Nach der Neuindizierung zu verkleinern ist sinnlos!

Sie werden den Index nur neu fragmentieren! Durch das Verkleinern wird die Lücke entfernt, indem Daten in der Datenbank neu zugeordnet werden.

Hier ist ein netter Artikel von Paul Randal, der bei Microsoft für den DBCCCode verantwortlich war, einschließlich der Verkleinerungen, warum Sie nicht verkleinern sollten.

JNK
quelle
0

Sie sollten die Neuaufbauoption verwendet haben SORT_IN_TEMPDB=ON.

In Ihrem Fall wurden die tatsächlichen Datendateien, in denen sich die fraglichen Tabellen befinden, zum Sortieren der Indizes verwendet. Ein Großteil dieser 120 GB Speicherplatz ist noch nicht belegt und wird bei Bedarf mit Seitendaten gefüllt.

Mit dieser Abfrage können Sie den Status des belegten / freien Speicherplatzes sehen (von hier aus ):

use [YourDatabaseNameHere]
go

select
    name,
    cast((size/128.0) as int) as TotalSpaceInMB,
    cast((cast(fileproperty(name, 'SpaceUsed') as int)/128.0) as int) as UsedSpaceInMB,
    cast((size/128.0 - cast(fileproperty(name, 'SpaceUsed') AS int)/128.0) as int) as FreeSpaceInMB
from
    sys.database_files

Informationen zum Verkleinern einer bestimmten Datenbankdatei (Daten oder Protokoll) finden Sie hier . Eine Warnung davor, dass das Freigeben von ungenutztem Speicherplatz für Datenbanken mit mehr als 100 GB ziemlich lange dauert (hängt auch von der Speichergeschwindigkeit ab), lassen Sie es also einfach laufen.

Marcel N.
quelle
Ja, es wird nicht formatiert, ich werde es in einem Moment der Frage hinzufügen.
@ JeffBane: Können Sie diese Informationen in einem Zitat zu Ihrer Frage hinzufügen? Ich kann nicht erkennen, was da drin ist.
Marcel N.
1
Wenn Sie einen Index neu erstellen, benötigen Sie den doppelten Platz des Index + 20% für die Sortierung. Um also jeden Index in Ihrer Datenbank neu zu erstellen, benötigen Sie im Allgemeinen nur 120% Ihres größten Index in Ihrer Datenbank. Wenn Sie SORT_IN_TEMPDB verwenden, gewinnen Sie nur 20%, Sie benötigen jedoch weitere 100% in Ihrer Datendatei. Darüber hinaus erhöht die Verwendung von sort in tempdb die E / A-Last drastisch, da Sie den Index nicht nur einmal in die Datendatei schreiben, sondern ihn nun einmal in die Tempdb und anschließend in die Datendatei schreiben. Das ist also nicht immer ideal.
Edward Dortland
-1

Ich vermute, dass Sie ohne weitere Details eine Transaktionsprotokollsicherung durchführen müssen, um den Speicherplatz freizugeben.

Sehen Sie, was select name, log_reuse_wait_desc from sys.databasesIhnen sagt. Wenn in der Spalte log_reuse_wait_desc angegeben LOG_BACKUPist, kann kein Speicherplatz mehr beansprucht werden, bis Sie eine Sicherungskopie des Übertragungsprotokolls erstellt haben.

dpw
quelle
Wenn Sie eine Transaktionsprotokollsicherung durchführen müssen, werden die Seiten nie freigegeben.
Mrdenny