Aumentar la columna de alteración de velocidad en una mesa grande a NO NULL

12

Recientemente agregué una columna de bits con capacidad NULL a una tabla que tiene cerca de 500 millones de filas. No hay un valor predeterminado en la columna, sin embargo, todas las inserciones están especificando un valor de 0 o 1, y ejecuté una rutina única para asignar 0 o 1 a todas las filas existentes (actualizando las filas en lotes pequeños). Cada fila ahora debería tener un 0 o 1 en esa columna.

Quiero que la columna de bits no sea anulable, sin embargo, cuando intenté hacerlo a través de ALTER TABLE t1 ALTER COLUMN c1 bit not null, comenzó a ejecutarse durante 3 minutos y la detuve porque estaba bloqueando todas las lecturas de la tabla y sospeché que iba a tomar mucho tiempo completarla . Es posible que no tarde demasiado, pero no podría arriesgarme a una gran falta de disponibilidad. El retroceso en sí tomó 6 minutos.

¿Tiene alguna sugerencia sobre cómo puedo hacer que la columna no sea anulable sin que tarde potencialmente horas en completarse? Además, ¿hay alguna forma de estimar cuánto tiempo ALTER TABLE ALTER COLUMNtardaría en completarse el estado de cuenta que comencé y luego cancelé?

Estoy usando SQL Server 2017 Web Edition.

Ben Amada
fuente

Respuestas:

12

En lugar de cambiar la definición de la columna, puede agregar una CHECK CONSTRAINTque no permita NULL para esa columna. Aún será necesario escanear la tabla, pero no tendrá que modificar cada página de datos, por lo que debería ser una operación mucho más rápida. Lamentablemente, todavía se mantendrá una cerradura Sch-M durante la operación. Un truco es tratar de obtener la mayor cantidad posible de la tabla en el grupo de búferes antes de intentar agregar la restricción. Eso puede reducir la cantidad de tiempo que se mantiene el bloqueo Sch-M.

Luego puede eliminar la restricción y cambiar la definición de columna durante su próxima ventana de mantenimiento.

Joe Obbish
fuente
Gracias Joe por la idea. Estuve a punto de agregar una restricción de verificación, pero tuve una ventana de mantenimiento durante el fin de semana y pude alterar la columna para que no sea anulable. No estoy seguro de si ayudó, pero para tratar de obtener los datos de la tabla en el grupo de búferes, justo antes de hacer que la columna no sea anulable, ejecuté, SELECT c1, count(*) FROM t1 GROUP BY c1que tardó aproximadamente 9 minutos en ejecutarse. La ALTER TABLE ALTER COLUMNdeclaración real después de eso tomó 25 minutos en completarse. No está mal.
Ben Amada
11

Si está en Enterprise Edition (EE), una mejor estrategia podría haber sido agregarlo como NOT NULLpredeterminado 0o 1(lo que sea más común).

Este es un cambio de metadatos solo en EE . Luego actualice los que necesitan ser volteados. Esto significa menos actualizaciones y no es necesario cambiar la nulabilidad de la columna cuando haya terminado. - martin-smith

usuario126897
fuente
Curiosamente, noté esta característica la semana pasada cuando probé agregar una columna de bits no anulable con un valor predeterminado a esta misma tabla grande en mi máquina local que ejecuta la edición de desarrollador SQL: la columna se agregó al instante y no pude entender por qué . Más tarde se me ocurrió que debía ser porque la edición para desarrolladores incluye características de EE.
Ben Amada
-3

Intente copiar los datos a una nueva tabla, luego cámbiele el nombre. Debe tener cuidado con las restricciones e índices. Eso es lo que está haciendo el diseñador de tablas SSMS cuando desea reordenar las columnas (por ejemplo), pero debe verificar el script para ver si hay algo que no se ve bien.

Durante la copia, el acceso de lectura a la tabla de origen no es un problema, pero si hay escrituras, pueden bloquearse o no copiarse, según el nivel de aislamiento.

Razvan Socol
fuente