Quando você altera uma coluna para NOT NULL, o SQL Server precisa tocar em todas as páginas, mesmo se não houver valores NULL. Dependendo do fator de preenchimento, isso pode levar a muitas divisões de página. É claro que todas as páginas tocadas precisam ser registradas, e suspeito que, devido às divisões, duas alterações possam ter que ser registradas para muitas páginas. Porém, como tudo é feito em uma única passagem, o log deve contabilizar todas as alterações para que, se você clicar em cancelar, saiba exatamente o que desfazer.
Um exemplo. Tabela simples:
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
Agora, vejamos os detalhes da página. Primeiro, precisamos descobrir com que página e DB_ID estamos lidando. No meu caso, criei um banco de dados chamado foo
e o DB_ID passou a ser 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
A saída indicava que eu estava interessado na página 159 (a única linha na DBCC IND
saída com PageType = 1
).
Agora, vejamos alguns detalhes da página selecionados à medida que avançamos no cenário do OP.
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);
Agora, eu não tenho todas as respostas para isso, porque eu não sou um cara interno profundo. Mas é claro que - embora a operação de atualização e a adição da restrição NOT NULL sejam inegavelmente gravadas na página - a última o faz de uma maneira totalmente diferente. Parece realmente alterar a estrutura do registro, em vez de apenas mexer nos bits, trocando a coluna anulável por uma coluna não anulável. Por que isso precisa ser feito, não tenho muita certeza - uma boa pergunta para a equipe do mecanismo de armazenamento , eu acho. Acredito que o SQL Server 2012 lida com alguns desses cenários muito melhor, FWIW - mas ainda não fiz testes exaustivos.
NOT NULL
coluna com um padrão como uma operação de metadados. Consulte também "Adicionando colunas NOT NULL como uma operação online" na documentação .