Zwiększ kolumnę zmieniającą prędkość na dużym stole do NON NULL

12

Niedawno dodałem kolumnę bitową obsługującą NULL do tabeli, która ma prawie 500 milionów wierszy. W kolumnie nie ma wartości domyślnej, jednak wszystkie wstawki określają wartość 0 lub 1, a ja uruchomiłem jednorazową procedurę, aby przypisać 0 lub 1 do wszystkich istniejących wierszy (aktualizując wiersze małymi partiami). Każdy wiersz powinien mieć teraz 0 lub 1 w tej kolumnie.

Chcę, aby kolumna bitowa nie miała wartości zerowej, jednak gdy spróbowałem to zrobić ALTER TABLE t1 ALTER COLUMN c1 bit not null, zaczęła działać przez 3 minuty i zatrzymałem ją, ponieważ blokowała wszystkie odczyty w tabeli i podejrzewałem, że jej ukończenie zajmie dużo czasu . Możliwe, że nie zajmie to zbyt długo, ale nie mogłem zaryzykować zbyt dużej niedostępności. Samo wycofanie zajęło 6 minut.

Czy masz jakieś sugestie na temat tego, jak sprawić, by kolumna nie miała wartości zerowej bez wypełnienia jej potencjalnie godzinami? Ponadto czy jest jakiś sposób oszacowania, ile ALTER TABLE ALTER COLUMNczasu zajęłoby uruchomienie, a następnie anulowanie wyciągu?

Korzystam z programu SQL Server 2017 Web Edition.

Ben Amada
źródło

Odpowiedzi:

12

Zamiast zmieniać definicję kolumny, możesz dodać taką CHECK CONSTRAINT, która nie zezwala na wartości NULL dla tej kolumny. Tabela nadal będzie musiała zostać przeskanowana, ale nie będzie musiała modyfikować każdej strony danych, więc powinna być znacznie szybsza. Niestety blokada Sch-M będzie nadal utrzymywana podczas operacji. Jedną sztuczką jest próba umieszczenia jak największej ilości tabeli w puli buforów przed próbą dodania ograniczenia. Może to skrócić czas przytrzymywania blokady Sch-M.

Następnie możesz usunąć ograniczenie i zmienić definicję kolumny podczas następnego okna konserwacji.

Joe Obbish
źródło
Dzięki Joe za pomysł. Prawie poszedłem z dodaniem ograniczenia sprawdzania, ale miałem weekend na konserwację i byłem w stanie zmienić kolumnę, aby nie miała wartości zerowej. Nie jestem pewien, czy to pomogło, ale próbując pobrać dane tabeli do puli buforów, tuż przed uczynieniem kolumny niedopuszczalną, uruchomiłem, SELECT c1, count(*) FROM t1 GROUP BY c1co trwało około 9 minut. Wypełnienie faktycznego ALTER TABLE ALTER COLUMNoświadczenia zajęło 25 minut. Nieźle.
Ben Amada,
11

Jeśli korzystasz z wersji Enterprise Edition (EE), lepszą strategią może być dodanie jej w NOT NULLwersji domyślnej 0lub 1(w zależności od tego, co jest najczęściej).

Jest to zmiana tylko EE w metadanych . Następnie zaktualizuj te, które muszą zostać odwrócone. Oznacza to mniej aktualizacji i nie trzeba zmieniać zerowalności kolumny po zakończeniu. - Martin Smith

126897
źródło
Co ciekawe, zauważyłem tę funkcję w zeszłym tygodniu, gdy testowałem dodanie niepozostawiającej wartości zerowej kolumny z wartością domyślną do tej samej dużej tabeli na moim komputerze lokalnym, na którym jest uruchomiona edycja deweloperska SQL - kolumna została dodana natychmiast i nie mogłem zrozumieć, dlaczego . Później zrozumiał, że tak musi być, ponieważ wersja dla programistów zawiera funkcje EE.
Ben Amada,
-3

Spróbuj skopiować dane do nowej tabeli, a następnie zmień nazwę. Musisz zadbać o wszelkie ograniczenia i indeksy. To właśnie robi projektant tabeli SSMS, jeśli chcesz zmienić kolejność kolumn (na przykład), ale powinieneś sprawdzić skrypt, aby sprawdzić, czy jest coś, co nie wygląda dobrze.

Podczas kopiowania dostęp do odczytu do tabeli źródłowej nie stanowi problemu, ale jeśli istnieją zapisy, mogą zostać zablokowane lub nie zostać skopiowane, w zależności od poziomu izolacji.

Razvan Socol
źródło