Wenn Sie eine Spalte in NOT NULL ändern, muss SQL Server jede einzelne Seite berühren , auch wenn keine NULL-Werte vorhanden sind. Abhängig von Ihrem Füllfaktor kann dies tatsächlich zu vielen Seitenteilen führen. Natürlich muss jede Seite, die berührt wird, protokolliert werden, und ich vermute aufgrund der Aufteilung, dass möglicherweise zwei Änderungen für viele Seiten protokolliert werden müssen. Da dies alles in einem einzigen Durchgang erledigt wird, muss das Protokoll alle Änderungen berücksichtigen, sodass es genau weiß, was rückgängig zu machen ist, wenn Sie auf Abbrechen klicken.
Ein Beispiel. Einfacher Tisch:
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
Schauen wir uns nun die Seitendetails an. Zuerst müssen wir herausfinden, mit welcher Seite und DB_ID wir es zu tun haben. In meinem Fall habe ich eine Datenbank namens erstellt foo
und die DB_ID war zufällig 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
Die Ausgabe zeigte an, dass ich an Seite 159 interessiert war (die einzige Zeile in der DBCC IND
Ausgabe mit PageType = 1
).
Schauen wir uns nun einige ausgewählte Seitendetails an, während wir das OP-Szenario durchlaufen.
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);
Jetzt habe ich nicht alle Antworten auf diese Frage, da ich kein Kerl mit tiefen Interna bin. Es ist jedoch klar, dass sowohl die Aktualisierungsoperation als auch die Hinzufügung der NOT NULL-Einschränkung unbestreitbar auf die Seite schreiben - letztere jedoch auf eine ganz andere Weise. Es scheint tatsächlich die Struktur des Datensatzes zu ändern, anstatt nur mit Bits herumzuspielen, indem die nullfähige Spalte durch eine nicht nullfähige Spalte ersetzt wird. Warum das so ist, weiß ich nicht genau - eine gute Frage für das Storage-Engine-Team , denke ich. Ich glaube, dass SQL Server 2012 einige dieser Szenarien viel besser handhabt, FWIW - aber ich muss noch keine umfassenden Tests durchführen.
NOT NULL
Spalte mit einem Standard als Metadatenvorgang hinzuzufügen . Siehe auch "Hinzufügen von NOT NULL-Spalten als Online-Operation" in der Dokumentation .