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 keine NULL
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 verhindert NULL
, dass Werte aus zukünftigen INSERT
oder UPDATE
Vorgängen erstellt werden, funktioniert dies.
Das Hinzufügen der Einschränkung kann sich jedoch weiterhin auf gleichzeitige Transaktionen auswirken. Sie ALTER TABLE
müssen Sch-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.
CREATE TABLE T (X INT NULL)
INSERT INTO T
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values
ALTER TABLE T WITH NOCHECK
ADD CONSTRAINT X_NOT_NULL
CHECK (X IS NOT NULL) ;
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Vergleichen Sie dies mit dem Einfacheren
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
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 als WITH 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.