Dependendo da alteração que você está fazendo, às vezes pode ser mais fácil fazer uma janela de manutenção. Durante essa janela (onde ninguém deve poder alterar os dados na tabela), você pode:
- elimine todos os índices/restrições que apontam para a coluna antiga e desative os acionadores
- adicionar um novo anulável coluna com o novo tipo de dados (mesmo que seja NOT NULL)
- atualize a nova coluna definindo-a igual ao valor da coluna antiga (e você pode fazer isso em partes de transações individuais (digamos, afetando 10.000 linhas por vez usando
UPDATE TOP (10000) ... SET newcol = oldcol WHERE newcol IS NULL
) e com CHECKPOINT para evitar ultrapassar seu log) - quando todas as atualizações estiverem concluídas, remova a coluna antiga
- renomeie a nova coluna (e adicione uma restrição NOT NULL, se apropriado)
- reconstrua índices e atualize estatísticas
A chave aqui é que ele permite que você execute a atualização incrementalmente na etapa 3, o que você não pode fazer em um único comando ALTER TABLE.
Isso pressupõe que a coluna não esteja desempenhando um papel importante na integridade dos dados - se estiver envolvida em vários relacionamentos de chave estrangeira, haverá mais etapas.
EDITAR
Além disso, e apenas me perguntando em voz alta, não fiz nenhum teste para isso (mas adicionei à lista). Gostaria de saber se a compactação de página + linha ajudaria aqui? Se você alterar um INT para um BIGINT, com a compactação em vigor, o SQL Server ainda deverá tratar todos os valores como se ainda couberem em um INT. Novamente, eu não testei se isso tornaria uma alteração mais rápida ou mais lenta, ou quanto mais tempo levaria para adicionar compactação em primeiro lugar. Só jogando lá fora.