Po zmianie kolumny na NOT NULL SQL Server musi dotykać każdej strony, nawet jeśli nie ma wartości NULL. W zależności od współczynnika wypełnienia może to prowadzić do wielu podziałów stron. Oczywiście każda dotknięta strona musi zostać zarejestrowana i podejrzewam, że ze względu na podziały w przypadku wielu stron konieczne może być zarejestrowanie dwóch zmian. Ponieważ wszystko dzieje się w jednym przejściu, dziennik musi uwzględniać wszystkie zmiany, aby po anulowaniu wiedział dokładnie, co należy cofnąć.
Przykład. Prosty stół:
DROP TABLE dbo.floob;
GO
CREATE TABLE dbo.floob
(
id INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
bar INT NULL
);
INSERT dbo.floob(bar) SELECT NULL UNION ALL SELECT 4 UNION ALL SELECT NULL;
ALTER TABLE dbo.floob ADD CONSTRAINT df DEFAULT(0) FOR bar
Teraz spójrzmy na szczegóły strony. Najpierw musimy dowiedzieć się, z jaką stroną i identyfikatorem DB_ID mamy do czynienia. W moim przypadku utworzyłem bazę danych o nazwie foo
, a zdarzeniem DB_ID było 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
Dane wyjściowe wskazują, że byłem zainteresowany stroną 159 (jedynym wierszem w DBCC IND
danych wyjściowych z PageType = 1
).
Teraz przyjrzyjmy się wybranym szczegółom strony, gdy przechodzimy przez scenariusz PO.
DBCC PAGE(5, 1, 159, 3);
UPDATE dbo.floob SET bar = 0 WHERE bar IS NULL;
DBCC PAGE(5, 1, 159, 3);
ALTER TABLE dbo.floob ALTER COLUMN bar INT NOT NULL;
DBCC PAGE(5, 1, 159, 3);
Teraz nie mam na to wszystkich odpowiedzi, ponieważ nie jestem facetem od głębokich chorób wewnętrznych. Ale jasne jest, że - chociaż zarówno operacja aktualizacji, jak i dodanie ograniczenia NOT NULL niezaprzeczalnie zapisują się na stronie - ta ostatnia robi to w zupełnie inny sposób. Wygląda na to, że faktycznie zmienia strukturę rekordu, zamiast po prostu bawić się bitami, zamieniając kolumnę null na kolumnę, która nie ma wartości null. Dlaczego tak się dzieje, nie jestem do końca pewien - wydaje mi się, że to dobre pytanie dla zespołu silnika pamięci masowej . Wierzę, że SQL Server 2012 radzi sobie z niektórymi z tych scenariuszy o wiele lepiej, FWIW - ale muszę jeszcze przeprowadzić wyczerpujące testy.
NOT NULL
kolumny z wartością domyślną jako operacji metadanych. Zobacz także „Dodawanie kolumn NOT NULL jako operacji online” w dokumentacji .