Коли ви змінюєте стовпець на NOT NULL, SQL Server повинен торкатися кожної окремої сторінки, навіть якщо немає значень NULL. Залежно від коефіцієнта заповнення, це фактично може призвести до розбиття сторінки. Кожна сторінка, яка торкнулася, звичайно, повинна бути зареєстрована, і я підозрюю через розбиття, що дві зміни, можливо, доведеться реєструвати на багатьох сторінках. Оскільки це все зроблено за один прохід, але журнал повинен враховувати всі зміни, щоб, якщо ви натиснете кнопку Скасувати, він точно знає, що скасувати.
Приклад. Проста таблиця:
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
Тепер давайте розглянемо деталі сторінки. Спочатку нам потрібно з’ясувати, на якій сторінці та DB_ID ми маємо справу. У моєму випадку я створив базу даних під назвою foo
, і DB_ID трапилася на 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
Результат вказав, що мене зацікавила сторінка 159 (єдиний рядок у DBCC IND
виведенні з PageType = 1
).
Тепер давайте розглянемо деякі деталі вибраної сторінки, переглядаючи сценарій роботи ОП.
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);
Зараз у мене немає всіх відповідей на це, оскільки я не є глибоким хлопцем. Але зрозуміло, що - хоча операція оновлення та додавання обмежень NOT NULL безперечно записуються на сторінку - остання робить це абсолютно по-іншому. Здається, насправді змінюється структура запису, а не просто поспіль з бітами, замінюючи нульовий стовпчик на стовпчик, що не зводиться нанівець. Чому це потрібно робити, я не зовсім впевнений - гарне питання для команди двигуна зберігання , я думаю. Я вважаю, що SQL Server 2012 обробляє деякі з цих сценаріїв набагато краще, FWIW - але я ще не повинен вичерпувати тестування.
NOT NULL
стовпця з типовою умовою як операція з метаданими. Також див. "Додавання стовпців NOT NULL як операція в Інтернеті" в документації .