Mam tabelę z milionami wierszy i kolumnę, która dopuszcza wartości NULL. Jednak żaden wiersz nie ma obecnie wartości NULL dla tej kolumny (mogę to dość szybko zweryfikować za pomocą zapytania). Jednak gdy wykonam polecenie
ALTER TABLE MyTable ALTER COLUMN MyColumn BIGINT NOT NULL;
zapytanie trwa wiecznie relatywnie rzecz biorąc. W rzeczywistości zajmuje to od 10 do 20 minut, ponad dwa razy dłużej niż dodanie ograniczenia sprawdzania. Czy istnieje sposób na natychmiastową aktualizację metadanych tabeli dla tej kolumny, zwłaszcza że wiem, że żaden wiersz nie ma wartości NULL dla tej kolumny?
sql-server-2008
null
alter-table
Joseph Daigle
źródło
źródło
Sch-M
blokadę, gdy zajmie to „na zawsze”. Czy chciałeś sprawdzić, czy czeka, czy jest zajęty?Odpowiedzi:
Odpowiedź @ ypercube radzi sobie z tym częściowo, ponieważ zmienia się tylko metadane.
Dodanie ograniczenia
NOCHECK
oznacza, że żadne wiersze nie będą musiały być czytane, aby je zweryfikować, a jeśli zaczynasz od pozycji, w której kolumna nie zawieraNULL
wartości (i jeśli wiesz, że żaden nie zostanie dodany między sprawdzaniem a dodawaniem ograniczenia), ponieważ ograniczenie uniemożliwia tworzenieNULL
wartości z przyszłościINSERT
lubUPDATE
operacji, to zadziała.Dodanie ograniczenia może jednak mieć wpływ na współbieżne transakcje.
ALTER TABLE
Będą musiały nabyćSch-M
blokadę pierwszy. Podczas oczekiwania na to wszystkie inne dostęp do tabeli zostaną zablokowane, jak opisano tutaj .Po uzyskaniu
Sch-M
blokady operacja powinna być jednak dość szybka.Jednym z problemów jest to, że nawet jeśli wiesz, że kolumna w rzeczywistości nie ma żadnych
NULL
ograniczeń, optymalizator zapytań nie ufa temu ograniczeniu, co oznacza, że plany mogą być nieoptymalne.Porównaj to z prostszym
Jednym z możliwych problemów, które możesz napotkać podczas zmiany definicji kolumny w ten sposób, jest to, że musi on nie tylko odczytać wszystkie wiersze, aby sprawdzić, czy spełniają warunek, ale może także faktycznie wykonać zarejestrowane aktualizacje wierszy .
Możliwym rozwiązaniem w połowie drogi może być dodanie ograniczenia sprawdzania
WITH CHECK
. Będzie to wolniejsze niżWITH NOCHECK
w przypadku konieczności odczytu wszystkich wierszy, ale pozwala optymalizatorowi zapytań podać prostszy plan w powyższym zapytaniu i powinno unikać potencjalnego problemu z zalogowanymi aktualizacjami.źródło
Zamiast zmieniać kolumnę można dodać
CHECK
ograniczenie tabeli za pomocąNOCHECK
opcji:źródło
NULL
ale nie będą mogły być używane przez optymalizator zapytań.ALTER COLUMN
po uzyskaniuSch-M
blokady, nie trzeba w ogóle skanować wierszy). Po prostu wskazując, że nie jest tak samo (np. Jeśli zostanie użyty wNOT IN
zapytaniu, plan będzie bardziej złożony)