Stworzyłem skrypt, który usuwa wszystkie klucze obce z bazy danych, tak jak poniżej:
ALTER TABLE MyTable1 DROP CONSTRAINT FK_MyTable1_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col1
ALTER TABLE MyTable2 DROP CONSTRAINT FK_MyTable2_col2
Zaskakuje mnie to, że skrypt zajmuje dużo czasu: średnio 20 sekund na każde DROP FK. Rozumiem teraz, że utworzenie FK może być dużym problemem, ponieważ serwer musi przejść i sprawdzić, czy ograniczenie FK nie jest naruszane od samego początku, ale spada? Co robi serwer, upuszczając FK tak długo? Dotyczy to zarówno mojej własnej ciekawości, jak i zrozumienia, czy istnieje sposób na przyspieszenie. Możliwość usunięcia FK (a nie tylko ich wyłączenia) pozwoliłaby mi być znacznie szybsza podczas migracji, a tym samym zminimalizować przestoje.
sql-server
foreign-key
sql-server-2016
carlo.borreo
źródło
źródło
Odpowiedzi:
Usunięcie ograniczenia wymaga blokady Sch-M (Modyfikacja schematu), która blokuje innym możliwość zapytania do tabeli podczas modyfikacji. Prawdopodobnie czekasz na tę blokadę i musisz poczekać, aż wszystkie aktualnie uruchomione zapytania dotyczące tej tabeli zostaną zakończone.
Uruchomione zapytanie ma blokadę Sch-S (Schema Stability) na stole i ta blokada jest niezgodna z blokadą Sch-M.
Z trybów blokady, blokad schematów
źródło
Sch-S
blokadę i podejrzewam, że jest to główna przyczyna problemów PO.Przedstawię ci przykład, abyś mógł zobaczyć, dlaczego zajęło to dużo czasu. Tworzenie pustej bazy danych dla tego testu.
Tworzenie 2 tabel.
Tworzenie ograniczenia klucza obcego w tabeli Person.
Wstaw niektóre dane do obu tabel.
Otwórz nowe okno zapytania i uruchom je (nie zamykaj okna po zakończeniu zapytania).
Otwórz kolejne okno zapytania i uruchom to.
Zobaczysz, że upuszczenie ograniczenia będzie nadal działać (czeka), a teraz uruchom zapytanie, aby zobaczyć, dlaczego działa dłużej i na jakie blokady czeka.
Po zatwierdzeniu operacji wstawiania ograniczenie upuszczania zostanie natychmiast zakończone, ponieważ teraz instrukcja drop może uzyskać wymaganą blokadę.
W twoim przypadku musisz upewnić się, że żadna sesja nie posiada kompatybilnej blokady, która zapobiegnie ograniczeniu upuszczenia w celu uzyskania niezbędnej blokady / blokad.
źródło