Temos uma tabela com 2,3 bilhões de linhas. Gostaríamos de alterar uma coluna de NOT NULL para NULL. A coluna está contida em um índice (não no índice clusterizado ou PK). O tipo de dados não está mudando (é um INT). Apenas a nulidade. A declaração é a seguinte:
Alter Table dbo.Workflow Alter Column LineId Int NULL
A operação demora mais de 10 antes de ser interrompida (nós ainda não a deixamos terminar porque é uma operação de bloqueio e estava demorando muito). Provavelmente copiaremos a tabela para um servidor dev para testar quanto tempo realmente leva. Mas, estou curioso para saber se alguém sabe o que o SQL Server está fazendo sob o capô ao converter de NOT NULL para NULL? Além disso, os índices afetados precisarão ser reconstruídos? O plano de consulta gerado não indica o que está acontecendo.
A tabela em questão é agrupada (não um heap).
Conforme mencionado por @Souplex nos comentários, uma possível explicação pode ser se esta coluna for a primeira
NULL
coluna capaz no índice não clusterizado do qual ela participa.Para a seguinte configuração
sys.dm_db_index_physical_stats mostra que o índice não clusterizado
ix
tem 248 páginas folha e uma única página raiz.Uma linha típica em uma página de folha de índice se parece com
E na página raiz
Então correndo...
Retornou
Verificando a folha de índice novamente, as linhas agora se parecem
e as linhas nas páginas de nível superior como abaixo.
Cada linha foi atualizada e agora contém dois bytes para a contagem de colunas junto com outro byte para o NULL_BITMAP.
Devido à largura de linha extra, o índice não clusterizado agora tem 285 páginas folha e agora duas páginas de nível intermediário junto com a página raiz.
O plano de execução do
parece o seguinte
Isso cria uma nova cópia do índice em vez de atualizar a existente e precisar dividir as páginas.
Ele definitivamente recriará o índice não clusterizado e não apenas atualizará os metadados. Isso é testado no SQL 2014 e realmente não deve ser testado em um sistema de produção:
E agora a parte divertida:
Isso nos dará as páginas do banco de dados onde a tabela e o índice não clusterizado são armazenados.
Encontre
PagePID
ondeIndexID
é 2 ePageType
é 2 e faça o seguinte:e depois:
Observe que há um bitmap nulo no cabeçalho:
Agora vamos fazer:
Se você estiver realmente impaciente, pode tentar executar o
dbcc page
comando novamente, mas ele falhará, então vamos verificar a alocação novamente comDBCC IND (0, z, -1)
. A página terá se movido como por mágica.Portanto, alterar a nulidade de uma coluna afetará o armazenamento de índices não clusterizados que cobrem essa coluna, pois os metadados precisam ser atualizados e você não precisa reconstruir os índices posteriormente.
Muitas
ALTER TABLE ... ALTER COLUMN ...
operações podem ser executadasONLINE
a partir do SQL Server 2016, mas: