Temos uma tabela com 2.3B 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 pará-la (ainda nem a concluímos porque é uma operação de bloqueio e está demorando muito). Provavelmente copiaremos a tabela para um servidor de desenvolvimento e testaremos quanto tempo realmente leva. Mas estou curioso para saber se alguém sabe o que o SQL Server está fazendo ao converter de NOT NULL para NULL? Além disso, os índices afetados precisam ser reconstruídos? O plano de consulta gerado não indica o que está acontecendo.
A tabela em questão está agrupada (não é uma pilha).
fonte
Respostas:
Como mencionado por @Souplex nos comentários, uma explicação possível pode ser se essa coluna for a primeira
NULL
coluna do índice não agrupado em que ela participa.Para a seguinte configuração
sys.dm_db_index_physical_stats mostra que o índice não agrupado
ix
possui 248 páginas em folha e uma única página raiz.Uma linha típica em uma página folha de índice é semelhante a
E na página raiz
Então correndo ...
Devolvida
Verificando novamente a folha de índice, as linhas agora 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, além de outro byte para o NULL_BITMAP.
Devido à largura extra da linha, o índice não agrupado agora tem 285 páginas de folha e agora duas páginas de nível intermediário junto com a página raiz.
O plano de execução para o
tem a seguinte aparência
Isso cria uma cópia totalmente nova do índice, em vez de atualizar a existente e precisar dividir as páginas.
fonte
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 em que a tabela e o índice não clusterizado estã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, tente 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 será movida como se por mágica.Portanto, alterar a nulidade de uma coluna afetará o armazenamento de índices não agrupados em cluster que cobrem essa coluna, pois os metadados precisam ser atualizados e você não precisará reconstruir os índices posteriormente.
Muitas
ALTER TABLE ... ALTER COLUMN ...
operações podem ser executadas aONLINE
partir do SQL Server 2016, mas:fonte