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-M
bloqueo 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
NOCHECK
significa que no será necesario leer filas para verificarlo, y si está comenzando desde una posición donde la columna no contieneNULL
valores (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ónNULL
valores que se crean a partir de futuroINSERT
o deUPDATE
operaciones, esto va a funcionar.Sin embargo, agregar la restricción aún puede tener un impacto en las transacciones concurrentes. El
ALTER TABLE
tendrá que adquirir unSch-M
bloqueo en primer lugar. Mientras espera esto, todos los demás accesos a la tabla serán bloqueados como se describe aquí .Sch-M
Sin 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
NULL
seguridad, 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 NOCHECK
lo 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
CHECK
restricción de tabla con laNOCHECK
opción:fuente
NULL
pero que el optimizador de consultas no podría utilizar.ALTER COLUMN
una vezSch-M
que 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 IN
consulta, el plan será más complejo)