Я создал скрипт, который по одному удаляет все внешние ключи из базы данных, вот так:
ALTER TABLE MyTable1 DROP CONSTRAINT FK_MyTable1_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col2
Что меня удивляет, так это то, что сценарий занимает много времени: в среднем 20 секунд для каждого DROP FK. Теперь я понимаю, что создание FK может иметь большое значение, потому что сервер должен пойти и проверить, что ограничение FK не нарушается с самого начала, а отбрасывается? Что делает сервер при отбрасывании FK, что занимает так много времени? Это как для моего собственного любопытства, так и для понимания, есть ли способ сделать вещи быстрее. Возможность удалить FK (а не просто отключить их) позволила бы мне быть намного быстрее во время миграции и, следовательно, минимизировать время простоя.
sql-server
foreign-key
sql-server-2016
carlo.borreo
источник
источник
Ответы:
Для удаления ограничения требуется блокировка Sch-M (изменение схемы), которая будет блокировать других для запроса таблицы во время модификации. Вы, вероятно, ожидаете, чтобы получить эту блокировку, и должны подождать, пока все текущие запросы к этой таблице не будут завершены.
Запущенный запрос имеет блокировку Sch-S (стабильность схемы) для таблицы, и эта блокировка несовместима с блокировкой Sch-M.
Из режимов блокировки, блокировки схемы
источник
Sch-S
блокировку, и я подозреваю, что это является основной причиной проблем OP.Я расскажу вам пример, и вы поймете, почему это заняло много времени. Создание пустой базы данных для этого теста.
Создание 2 таблиц.
Создание ограничения внешнего ключа для таблицы Person.
Вставьте некоторые данные в обе таблицы.
Откройте новое окно запроса и запустите его (не закрывайте окно после завершения запроса).
Откройте другое окно запроса и запустите это.
Вы увидите, что отбрасываемое ограничение будет продолжать работать (ждать), и теперь запустите запрос, чтобы увидеть, почему он работает дольше и каких блокировок он ожидает.
После того, как вы подтвердите операцию вставки, ограничение сброса будет немедленно выполнено, потому что теперь оператор drop может получить требуемую блокировку.
В вашем случае вам нужно убедиться, что ни один сеанс не удерживает совместимую блокировку, которая будет препятствовать сбросу ограничения для получения необходимых блокировок / блокировок.
источник