Tengo una tabla con millones de filas y una columna que permite valores NULL. Sin embargo, ninguna fila tiene actualmente un valor NULL para esa columna (puedo verificar esto bastante rápido con una consulta). Sin embargo cuando ejecuto el comando
ALTER TABLE MyTable ALTER COLUMN MyColumn BIGINT NOT NULL;
la consulta lleva una eternidad relativamente hablando. En realidad, toma entre 10 y 20 minutos, más del doble de tiempo que agregar una restricción de verificación. ¿Hay alguna manera de actualizar instantáneamente los metadatos de la tabla para esa columna, especialmente porque sé que ninguna fila tiene un valor NULL para esa columna?
sql-server-2008
null
alter-table
Joseph Daigle
fuente
fuente

Sch-Mbloqueo cuando se tarda "para siempre". ¿Miraste para ver si estaba esperando u ocupado?Respuestas:
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 contieneNULLvalores (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ónNULLvalores que se crean a partir de futuroINSERTo deUPDATEoperaciones, 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 unSch-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.Compare esto con el más simple
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 deWITH 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.fuente
Podría, en lugar de alterar la columna, agregar una
CHECKrestricción de tabla con laNOCHECKopción:fuente
NULLpero que el optimizador de consultas no podría utilizar.ALTER COLUMNuna vezSch-Mque se adquiere el bloqueo, esto no necesita escanear las filas en absoluto). Solo señalando que no es lo mismo (por ejemplo, si se usa en unaNOT INconsulta, el plan será más complejo)