He creado un script que, uno a la vez, elimina todas las claves foráneas de una base de datos, así:
ALTER TABLE MyTable1 DROP CONSTRAINT FK_MyTable1_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col2
Lo que me sorprende es que el guión lleva mucho tiempo: en promedio, 20 segundos por cada DROP FK. Ahora, entiendo que crear un FK puede ser un gran problema, porque el servidor tiene que ir y verificar que la restricción FK no se infringe desde el principio, sino que se cae. ¿Qué hace un servidor al soltar FK que lleva tanto tiempo? Esto es para mi propia curiosidad y para comprender si hay una manera de hacer las cosas más rápido. Ser capaz de eliminar FK (no solo deshabilitarlos) me permitiría ser mucho más rápido durante una migración y, por lo tanto, minimizar el tiempo de inactividad.
sql-server
foreign-key
sql-server-2016
carlo.borreo
fuente
fuente
Respuestas:
Eliminar una restricción requiere un bloqueo Sch-M (modificación de esquema) que bloqueará a otros para consultar la tabla durante la modificación. Probablemente esté esperando obtener ese bloqueo y tendrá que esperar hasta que finalicen todas las consultas que se ejecutan actualmente en esa tabla.
Una consulta en ejecución tiene un bloqueo Sch-S (Estabilidad de esquema) en la tabla y ese bloqueo es incompatible con un bloqueo Sch-M.
Desde modos de bloqueo, bloqueos de esquema
fuente
Sch-S
bloqueo, y sospecho que esta es la causa raíz de los problemas del OP.Te explicaré un ejemplo para que puedas ver por qué estaba tomando tanto tiempo. Crear una base de datos vacía para esta prueba.
Creando 2 tablas.
Creación de una restricción de clave externa en la tabla Persona.
Inserte algunos datos en ambas tablas.
Abra una nueva ventana de consulta y ejecútela (no cierre la ventana una vez que se complete la consulta).
Abra otra ventana de consulta y ejecute esto.
Verá que la restricción de caída continuará ejecutándose (esperando) y ahora ejecutará la consulta para ver por qué se está ejecutando por más tiempo y qué bloqueos está esperando.
Una vez que confirme su operación de inserción, la restricción de caída se completará inmediatamente porque ahora la declaración de caída puede adquirir el bloqueo requerido.
Para su caso, debe asegurarse de que ninguna sesión tenga un bloqueo compatible que evite la restricción de caída para adquirir los bloqueos / bloqueos necesarios.
fuente