Primeiras coisas primeiro: quantos dados existem na tabela? Número de linhas e tamanho da tabela?
Segundo: você pode fazer backup e restaurar esta tabela em um servidor de teste e executar a instrução alter para ver o impacto (supondo que não seja inviável devido ao fato de a tabela ser muito grande para caber em um sistema não de produção)? Eu sempre acho que os testes no meu ambiente são mais precisos que os conselhos das interwebs, pois existem vários fatores que podem influenciar o resultado que talvez não seja fornecido na pergunta simplesmente por não saberem que esses fatores podem afetar o resultado.
Terceiro: aumentar o tamanho de um campo de tamanho variável é (supondo que você não ultrapasse o limite de 8060 bytes) uma operação simples de metadados, pois nenhum dado real estaria mudando para essa operação. Mas, por outro lado, reduzir o tamanho de um campo de tamanho variável, mesmo para algo que funcionará mais do que obviamente, não é uma simples alteração de metadados porque o SQL Server não sabe, antes da varredura de todas as linhas , que o tamanho solicitado recentemente é válido.
Portanto: Sim, isso bloqueará a tabela por um período de tempo . Quanto tempo? Bem, aqui está o teste que eu acabei de fazer:
Eu tinha, de algum outro teste, uma tabela com um único INT NOT NULL
campo e 1 milhão de linhas. Copiei-o para uma nova tabela com o objetivo de fazer este teste via:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
Dessa maneira, eu estava começando com um cenário semelhante de ter um MAX
campo (acabei de perceber que você tem VARCHAR
e estou usando NVARCHAR
, mas isso não deve alterar o comportamento que estou vendo) para o qual eu poderia mudar 500
. E possui dados que podem caber facilmente em 500 caracteres. Isso levou alguns minutos.
Eu então corri:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
E isso levou pouco mais de 11 minutos.
Eu apenas refiz o teste novamente, desta vez descartando a [ResizeTest]
tabela e alterando os dois NVARCHAR
para serem justos VARCHAR
, apenas para ter certeza de que estou comparando maçãs com algo que pelo menos parece uma maçã ;-).
A criação da tabela inicial levou 20 segundos e ALTER TABLE
2 minutos.
Portanto, em termos de estimativa do tempo de inatividade, isso é realmente difícil, pois se baseia na velocidade de E / S do disco, se alguma operação de crescimento automático precisa ou não ocorrer no arquivo de dados e / ou no log de transações, etc. é provavelmente uma grande parte do motivo pelo qual meu primeiro teste levou 11 minutos para ser alterado e o segundo, mesmo com VARCHAR
a metade do tamanho dos NVARCHAR
dados, levou apenas 2 minutos (ou seja, os arquivos foram pré-desenvolvidos nesse ponto). Ainda assim, lembre-se de que meu teste está sendo executado no meu laptop, que não é o disco mais rápido, mas também eram apenas 1 milhão de linhas de 2 colunas pequenas (22 ou mais bytes por linha).
E como você perguntou o que isso fará com as páginas de dados, aqui está sua resposta. Eu fiz um sp_spaceused
depois de criar a tabela, depois de fazer o ALTER COLUMN
e depois de fazer ALTER TABLE dbo.ResizeTest REBUILD;
. Os resultados (os seguintes números são baseados no segundo teste usando VARCHAR
, não no primeiro teste usando NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
Se você estiver preocupado com a necessidade de manter a operação no menor tempo possível, confira um artigo que escrevi sobre como fazer isso: Reestruture 100 milhões de linhas (ou mais) de tabelas em segundos. SRSLY! (é necessário registro gratuito).
ALTER
ed cada coluna em sucessão - cada ação levou menos de um segundo. Quando terminaram, a tabela havia dobrado de tamanho, mas depois que eu fiz umaREBUILD
(que também era uma operação em um segundo), a tabela voltou ao tamanho original.ALTER TABLE
operação executando todos os campos de uma só vez, separando cada coluna com uma vírgula. Se a transação for muito grande, divida a tabela em 2 instruções ALTER de metade das colunas cada. E, dependendo do tamanho da tabela, você pode até fazer uma REBUILD entre cada uma das duas instruções ALTER. Algo para brincar. Além disso, lembre-se de que a operação provavelmente terá um bloqueio de esquema pela duração que bloqueará todo o acesso à tabela.ALTER
separadamente para poder acompanhar as mudanças de tamanho entre cada um, mas definitivamente bom saber. Obrigado!Pelo que reuni executando a declaração alter não deve demorar muito, desde que a mesa não esteja bloqueada por outro processo. De acordo com o gbn, é apenas uma alteração de metadados: /programming/7261909/is-it-bad-to-use-alter-table-to-resize-a-varchar-column-to-a-larger -Tamanho
Além disso, quanto à maneira como eles são armazenados, parece que o SQL Server armazenou os dados do varchar em uma página de 8k até preencher uma página inteira, que neste momento o substitui por um ponteiro e os armazena como um BLOB.
Estou assumindo que quando você altera o comprimento, não estará truncando nenhum registro. Nesse caso, no máximo os dados que você está convertendo para varchar (500) devem ter no máximo 502 bytes e não devem ter um ponteiro.
Portanto, para encurtar a história, pouco deve mudar desde que você não esteja truncando nenhum dado.
fonte