Das Wichtigste zuerst: Wie viele Daten enthält die Tabelle? Anzahl der Zeilen und Größe der Tabelle?
Zweitens: Können Sie diese Tabelle auf einem Testserver sichern und wiederherstellen und die alter-Anweisung ausführen, um die Auswirkungen zu ermitteln (vorausgesetzt, sie ist nicht unmöglich, da die Tabelle für ein Nichtproduktionssystem zu groß ist)? Ich finde immer, dass das Testen in meiner Umgebung genauer ist als die Empfehlungen aus den Interwebs, da es mehrere Faktoren gibt, die das Ergebnis beeinflussen können, die in der Frage möglicherweise nicht angegeben werden, weil nicht bekannt ist, dass diese Faktoren das Ergebnis beeinflussen können.
Drittens: Das Erhöhen der Größe eines Felds mit variabler Länge ist (vorausgesetzt, Sie überschreiten nicht die 8060-Byte-Grenze) eine einfache Metadatenoperation, da sich für eine solche Operation keine tatsächlichen Daten ändern würden. ABER auf der anderen Seite ist es keine einfache Metadatenänderung , die Größe eines Felds mit variabler Länge zu reduzieren , selbst wenn dies mehr als offensichtlich funktioniert, da SQL Server vor dem Durchsuchen aller Zeilen nicht weiß , dass die neu angeforderte Größe gültig ist.
Daher: Ja, dies sperrt die Tabelle für einen bestimmten Zeitraum . Wie viel Zeit? Nun, hier ist der Test, den ich gerade gemacht habe:
Aus anderen Tests ging hervor, dass ich eine Tabelle mit einem einzigen INT NOT NULL
Feld und 1 Million Zeilen hatte. Ich habe es in eine neue Tabelle kopiert, um diesen Test durchzuführen:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
Auf diese Weise begann ich mit einem ähnlichen Szenario, in dem ich ein MAX
Feld hatte (ich habe gerade festgestellt, dass Sie ein Feld haben VARCHAR
und das ich verwende NVARCHAR
, aber das sollte das Verhalten, das ich sehe, nicht ändern), das ich dann ändern könnte 500
. Und es enthält Daten, die problemlos in 500 Zeichen passen. Das hat ein paar Minuten gedauert.
Ich lief dann:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
Und das dauerte etwas mehr als 11 Minuten.
Ich habe den Test gerade noch einmal wiederholt, diesmal habe ich den [ResizeTest]
Tisch fallen lassen und beide NVARCHAR
geändert, um nur zu sein VARCHAR
, um sicherzugehen, dass ich Äpfel mit etwas vergleiche, das zumindest wie ein Apfel aussieht ;-).
Die anfängliche Tabellenerstellung dauerte 20 Sekunden, während die Erstellung ALTER TABLE
2 Minuten dauerte.
In Bezug auf die Schätzung der Ausfallzeit ist dies wirklich schwierig, da es auf den E / A-Geschwindigkeiten der Festplatte beruht und es keine automatischen Wachstumsvorgänge für die Datendatei und / oder das Transaktionsprotokoll usw. geben muss Dies ist wahrscheinlich ein wesentlicher Grund dafür, warum mein erster Test 11 Minuten in Anspruch nahm und der zweite, obwohl VARCHAR
er nur halb so groß war wie die NVARCHAR
Daten, nur 2 Minuten in Anspruch nahm (dh die Dateien wurden zu diesem Zeitpunkt vorgewachsen). Sie sollten jedoch bedenken, dass mein Test auf meinem Laptop ausgeführt wird, der nicht die schnellste Festplatte ist, aber es waren auch nur 1 Million Zeilen mit 2 kleinen Spalten (etwa 22 Byte pro Zeile).
Und da Sie gefragt haben, was es mit den Datenseiten machen soll, ist hier Ihre Antwort. Ich habe eine sp_spaceused
nach dem Erstellen der Tabelle, nach dem Ausführen der ALTER COLUMN
und nach dem Ausführen ALTER TABLE dbo.ResizeTest REBUILD;
. Die Ergebnisse (die folgenden Zahlen basieren auf dem zweiten Test mit VARCHAR
, nicht dem ersten Test mit NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
Wenn Sie Bedenken haben, den Vorgang so kurz wie möglich zu halten, lesen Sie einen Artikel, in dem ich genau das beschrieben habe: Restrukturieren Sie 100-Millionen-Zeilen-Tabellen (oder mehr) in Sekunden. SRSLY! (kostenlose Registrierung erforderlich).
ALTER
jede Spalte nacheinander bearbeitet - jede Aktion dauerte weniger als eine Sekunde. Als sie fertig waren, hatte sich die Größe des Tisches verdoppelt, aber als ich eineREBUILD
Operation (die auch eine Operation unter einer Sekunde war) durchführte, kehrte der Tisch zu seiner ursprünglichen Größe zurück.ALTER TABLE
Vorgang wahrscheinlich beschleunigen, indem Sie alle Felder auf einmal ausführen und jede Spalte durch ein Komma trennen. Wenn die Transaktion zu groß ist, teilen Sie die Tabelle in 2 ALTER-Anweisungen mit jeweils der Hälfte der Spalten auf. Und je nachdem, wie groß die Tabelle wird, können Sie zwischen den beiden ALTER-Anweisungen sogar ein REBUILD durchführen. Etwas zum Spielen. Beachten Sie auch, dass die Operation wahrscheinlich für die Dauer eine Schemasperre benötigt, die den gesamten Zugriff auf die Tabelle blockiert.ALTER
sich gemacht, um die Größenänderungen zwischen den einzelnen zu verfolgen, aber auf jeden Fall gut zu wissen. Vielen Dank!Soweit ich weiß, sollte die Ausführung der alter-Anweisung nicht sehr lange dauern, solange der Tisch nicht durch einen anderen Prozess gesperrt ist. Laut gbn handelt es sich lediglich um eine Metadatenänderung: /programming/7261909/is-it-bad-to-use-alter-table-to-resize-a-varchar-column-to-a-larger -Größe
Außerdem scheint es, als ob SQL Server die varchar-Daten in einer 8-KB-Seite gespeichert hat, bis sie eine ganze Seite ausfüllen. An diesem Punkt wird sie durch einen Zeiger ersetzt und als BLOB gespeichert.
Ich gehe davon aus, dass Sie beim Ändern der Länge keine Datensätze abschneiden. Wenn ja, sollten die Daten, die Sie in varchar (500) konvertieren, höchstens 502 Byte lang sein und keinen Zeiger haben.
Kurz gesagt, es sollte sich nicht viel ändern, solange Sie keine Daten abschneiden.
quelle