Mamy tabelę z rzędami 2.3B. Chcielibyśmy zmienić kolumnę z NOT NULL na NULL. Kolumna jest zawarta w jednym indeksie (nie indeks klastrowany ani indeks PK). Typ danych się nie zmienia (jest to INT). Po prostu nullability. Oświadczenie jest następujące:
Alter Table dbo.Workflow Alter Column LineId Int NULL
Operacja trwa ponad 10, zanim ją zatrzymamy (jeszcze nie dopuściliśmy do jej zakończenia, ponieważ jest to operacja blokująca i trwała zbyt długo). Prawdopodobnie skopiujemy tabelę na serwer deweloperski w celu sprawdzenia, jak długo to faktycznie potrwa. Ale jestem ciekawy, czy ktoś wie, co robi SQL Server pod maską podczas konwersji z NOT NULL na NULL? Czy indeksy, których to dotyczy, będą musiały zostać odbudowane? Wygenerowany plan zapytań nie wskazuje, co się dzieje.
Tabela, o której mowa, jest klastrowana (nie kupa).
źródło
Odpowiedzi:
Jak wspomniano w @Souplex w komentarzach, jednym z możliwych wyjaśnień może być to, że kolumna ta jest pierwszą
NULL
kolumną z możliwością indeksowania w indeksie nieklastrowanym, w którym uczestniczy.Dla następującej konfiguracji
sys.dm_db_index_physical_stats pokazuje, że nieklastrowany indeks
ix
ma 248 stron liści i jedną stronę główną.Wygląda typowy wiersz na stronie liścia indeksu
I na stronie głównej
Następnie bieganie ...
Zwrócony
Ponownie sprawdzając liść indeksu, wyglądają teraz wiersze
oraz wiersze na stronach wyższego poziomu, jak poniżej.
Każdy wiersz został zaktualizowany i teraz zawiera dwa bajty dla liczby kolumn wraz z innym bajtem dla NULL_BITMAP.
Ze względu na dodatkową szerokość wiersza indeks nieklastrowany ma teraz 285 stron liści, a teraz dwie strony poziomu pośredniego wraz ze stroną główną.
Plan wykonania dla
wygląda następująco
Spowoduje to utworzenie zupełnie nowej kopii indeksu zamiast aktualizowania istniejącej i konieczności dzielenia stron.
źródło
Na pewno odtworzy indeks nieklastrowany, a nie tylko zaktualizuje metadane. Jest to testowane na SQL 2014 i naprawdę nie powinno być testowane w systemie produkcyjnym:
A teraz część zabawy:
To da nam strony bazy danych, w których przechowywana jest tabela i indeks nieklastrowany.
Znajdź
PagePID
gdzieIndexID
2 iPageType
2, a następnie wykonaj następujące czynności:i wtedy:
Zauważ, że w nagłówku znajduje się pusta mapa bitowa:
Teraz zróbmy:
Jeśli jesteś naprawdę niecierpliwy, możesz spróbować ponownie uruchomić
dbcc page
polecenie, ale to się nie powiedzie, więc sprawdźmy ponownie przydział za pomocąDBCC IND (0, z, -1)
. Strona zostanie przeniesiona jak za pomocą magii.Tak więc zmiana zerowalności kolumny wpłynie na przechowywanie indeksów nieklastrowych pokrywających tę kolumnę, ponieważ metadane muszą zostać zaktualizowane, a później nie trzeba będzie odbudowywać indeksów.
Wiele
ALTER TABLE ... ALTER COLUMN ...
operacji można wykonaćONLINE
począwszy od SQL Server 2016, ale:źródło