Ich habe eine Tabelle mit Millionen von Zeilen und eine Spalte, die Nullwerte zulässt. Derzeit hat jedoch keine Zeile einen NULL-Wert für diese Spalte (dies kann ich relativ schnell mit einer Abfrage überprüfen). Jedoch wenn ich den Befehl ausführe
ALTER TABLE MyTable ALTER COLUMN MyColumn BIGINT NOT NULL;
Die Abfrage dauert relativ gesehen ewig . Tatsächlich dauert es zwischen 10 und 20 Minuten, mehr als doppelt so lange wie das Hinzufügen einer Prüfbedingung. Gibt es eine Möglichkeit, die Metadaten der Tabelle für diese Spalte sofort zu aktualisieren, zumal ich weiß, dass keine Zeile einen NULL-Wert für diese Spalte hat?
sql-server-2008
null
alter-table
Joseph Daigle
quelle
quelle
Sch-M
Sperre, wenn es "für immer" dauert. Haben Sie nachgesehen, ob es gewartet hat oder beschäftigt ist?Antworten:
Die Antwort von @ypercube verwaltet dies teilweise, da sich nur die Metadaten ändern.
Das Hinzufügen der Einschränkung mit
NOCHECK
bedeutet, dass keine Zeilen gelesen werden müssen, um sie zu überprüfen. Wenn Sie an einer Position beginnen, an der die Spalte keineNULL
Werte enthält (und wenn Sie wissen, dass zwischen dem Überprüfen und Hinzufügen der Einschränkung keine hinzugefügt werden), Da die Einschränkung verhindertNULL
, dass Werte aus zukünftigenINSERT
oderUPDATE
Vorgängen erstellt werden, funktioniert dies.Das Hinzufügen der Einschränkung kann sich jedoch weiterhin auf gleichzeitige Transaktionen auswirken. Sie
ALTER TABLE
müssenSch-M
zuerst eine Sperre erwerben . Während des Wartens werden alle anderen Tabellenzugriffe wie hier beschrieben gesperrt .Sobald die
Sch-M
Sperre erreicht ist, sollte die Operation jedoch ziemlich schnell sein.Ein Problem dabei ist, dass selbst wenn Sie wissen, dass die Spalte tatsächlich keine
NULL
s enthält, der Einschränkung vom Abfrageoptimierer nicht vertraut wird, was bedeutet, dass die Pläne suboptimal sein können.Vergleichen Sie dies mit dem Einfacheren
Ein mögliches Problem, das beim Ändern der Spaltendefinition auf diese Weise auftreten kann, besteht darin, dass nicht nur alle Zeilen gelesen werden müssen, um zu überprüfen, ob sie die Bedingung erfüllen, sondern auch protokollierte Aktualisierungen für die Zeilen ausgeführt werden können .
Ein möglicher Zwischenstopp könnte darin bestehen, die Prüfbedingung hinzuzufügen
WITH CHECK
. Dies ist langsamer alsWITH NOCHECK
das Lesen aller Zeilen, aber es ermöglicht dem Abfrageoptimierer, den einfacheren Plan in der obigen Abfrage anzugeben, und es sollte das mögliche Problem mit protokollierten Aktualisierungen vermeiden.quelle
Anstatt die Spalte zu ändern, können Sie eine Tabelleneinschränkung
CHECK
mit der folgendenNOCHECK
Option hinzufügen :quelle
NULL
erzeugen, aber nicht vom Abfrageoptimierer verwendet werden können.ALTER COLUMN
wenn dieSch-M
Sperre einmal erlangt wurde, müssen die Zeilen überhaupt nicht gescannt werden). Ich möchte nur darauf hinweisen, dass es nicht ganz dasselbe ist (z. B. wennNOT IN
der Plan in einer Abfrage verwendet wird, wird er komplexer)