Je nachdem, welche Änderung Sie vornehmen, kann es manchmal einfacher sein, ein Wartungsfenster zu nehmen. Während dieses Fensters (wo niemand in der Lage sein sollte, die Daten in der Tabelle zu ändern) können Sie:
- Löschen Sie alle Indizes/Einschränkungen, die auf die alte Spalte verweisen, und deaktivieren Sie Trigger
- fügen Sie eine neue nullable hinzu Spalte mit dem neuen Datentyp (auch wenn er NOT NULL sein soll)
- aktualisiere die neue Spalte, indem du sie gleich dem Wert der alten Spalte setzt (und du kannst dies in Blöcken einzelner Transaktionen tun (z. B. 10000 Zeilen gleichzeitig mit
UPDATE TOP (10000) ... SET newcol = oldcol WHERE newcol IS NULL
) und mit CHECKPOINT, um ein Überlaufen Ihres Protokolls zu vermeiden) - Sobald die Aktualisierungen abgeschlossen sind, löschen Sie die alte Spalte
- Benennen Sie die neue Spalte um (und fügen Sie gegebenenfalls eine NOT NULL-Einschränkung hinzu)
- Indizes neu erstellen und Statistiken aktualisieren
Der Schlüssel hier ist, dass Sie die Aktualisierung in Schritt 3 inkrementell durchführen können, was Sie nicht mit einem einzigen ALTER TABLE-Befehl tun können.
Dies setzt voraus, dass die Spalte keine große Rolle bei der Datenintegrität spielt – wenn sie an einer Reihe von Fremdschlüsselbeziehungen beteiligt ist, sind weitere Schritte erforderlich.
BEARBEITEN
Außerdem, und ich wundere mich nur laut, habe ich keine Tests dafür durchgeführt (aber es der Liste hinzugefügt). Ich frage mich, ob die Seiten- und Zeilenkomprimierung hier helfen würde? Wenn Sie einen INT in einen BIGINT ändern, sollte SQL Server bei vorhandener Komprimierung alle Werte weiterhin so behandeln, als ob sie noch in einen INT passen würden. Auch hier habe ich nicht getestet, ob dies eine Änderung schneller oder langsamer machen würde oder wie viel länger es dauern würde, die Komprimierung überhaupt hinzuzufügen. Wirf es einfach raus.