La respuesta de @ypercube logra esto parcialmente como un cambio de metadatos solamente.
Agregar la restricción con NOCHECKsignifica que no será necesario leer filas para verificarlo, y si está comenzando desde una posición donde la columna no contiene NULLvalores (y si sabe que no se agregará ninguno entre la verificación y la adición de la restricción), entonces, como los previene de restricción NULLvalores que se crean a partir de futuro INSERTo de UPDATEoperaciones, esto va a funcionar.
Sin embargo, agregar la restricción aún puede tener un impacto en las transacciones concurrentes. El ALTER TABLEtendrá que adquirir un Sch-Mbloqueo en primer lugar. Mientras espera esto, todos los demás accesos a la tabla serán bloqueados como se describe aquí .
Sch-MSin embargo, una vez que se obtiene el bloqueo, la operación debería ser bastante rápida.
Un problema con esto es que, incluso si sabe que la columna de hecho no tiene NULLseguridad, el optimizador de consultas no confía en la restricción, lo que significa que los planes pueden ser subóptimos.
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)

Compare esto con el más simple
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)

Un posible problema que puede encontrar al alterar la definición de columna de esta manera es que no solo necesita leer todas las filas para verificar que cumplan con la condición, sino que también puede terminar realizando actualizaciones registradas en las filas .
Una posible casa a mitad de camino podría ser agregar la restricción de verificación WITH CHECK. Esto será más lento de WITH NOCHECKlo que necesita para leer todas las filas, pero permite que el optimizador de consultas proporcione el plan más simple en la consulta anterior y debería evitar el posible problema de actualizaciones registradas.