Como reduzir o tamanho da tabela SQL Server que cresceu a partir de uma mudança de tipo de dados

StackOverflow https://stackoverflow.com/questions/807579

Pergunta

Eu tenho uma tabela no SQL Server 2005 que foi de cerca de 4 GB de tamanho.

(cerca de 17 milhões de discos)

I mudou um dos domínios de tipo de dados char(30) para char(60) (existem um total de 25 campos a maioria dos quais são char(10) assim que a quantidade de espaço de char adiciona-se a cerca de 300)

Isso fez com que a tabela para dobrar de tamanho (mais de 9 GB)

I então mudado o char(60) para varchar(60) e, em seguida, correu uma função para cortar espaços em branco adicionais fora dos dados (de modo a reduzir a duração média dos dados no campo a cerca de 15)

Esta não reduzir o tamanho da tabela. Encolhendo o banco de dados não quer ajudar.

curto de realmente recriar a estrutura da tabela e copiar os dados mais (que é de 17 milhões de registros!) Há uma maneira menos drástica de obter o tamanho de volta para baixo novamente?

Foi útil?

Solução

Bem, é claro que você não está recebendo qualquer volta espaço! : -)

Quando você mudou seus campos de texto para CHAR (60), eles estão todos cheios até a capacidade com espaços. Então todos os seus campos são agora realmente 60 caracteres.

A alteração que volta para VARCHAR (60) não ajuda - os campos ainda estão todos os 60 caracteres longa ....

O que você realmente precisa fazer é executar uma função TRIM sobre todos os seus campos para reduzi-los de volta ao seu comprimento aparado, e depois fazer um banco de dados encolhendo.

Depois de ter feito isso, você precisa para reconstruir o seu índice de cluster, a fim de recuperar algum desse espaço desperdiçado. O índice de cluster é realmente onde suas vidas dados - você pode reconstruí-lo como este:

ALTER INDEX IndexName ON YourTable REBUILD 

Por padrão, sua chave primária é o seu índice de cluster (a menos que especificado em contrário).

Marc

Outras dicas

Você não limpar ou compactar os dados, mesmo com um "encolher banco de dados".

DBCC CLEANTABLE

espaço Recupera a partir de colunas de comprimento variável caiu em tabelas ou exibições indexadas.

No entanto, um índice simples reconstruir < em> se houver um índice de cluster também deve fazê-lo

ALTER INDEX ALL ON dbo.Mytable REBUILD

Um exemplo trabalhou de Tony Rogerson

Eu sei que não estou respondendo a sua pergunta como você está pedindo, mas você já pensou em arquivar alguns dos dados a uma tabela de história, e trabalhar com menos linhas?

Na maioria das vezes você pode pensar à primeira vista que você precisa todos os dados o tempo todo, mas quando realmente sentar e examinando-o, há casos em que isso não é verdade. Ou pelo menos eu experimentei essa situação antes.

Eu tive um problema semelhante aqui SQL Server, convertendo NTEXT para NVARCHAR (MAX) que foi relacionada com a mudança ntext para nvarchar (max).

Eu tive que fazer uma UPDATE MyTable SET MyValue = MyValue, a fim de obtê-lo para redimensionar tudo bem.

Isto, obviamente, leva um bom tempo com um monte de registros. Havia uma série de sugestões sobre a melhor forma de fazê-lo. Eles uma chave era uma bandeira temporária indicado se tivesse sido feito ou não e, em seguida, atualizar alguns milhares de cada vez em um loop até que foi tudo feito. Isso significava que eu tinha "alguns" controle sobre o quanto ele estava fazendo.

Em outra nota, porém, se você realmente deseja reduzir o banco de dados, tanto quanto possível, pode ajudar se você transformar o modelo de recuperação até simples, encolher os logs de transação, reorganizar todos os dados das páginas, em seguida, configurá-lo voltar ao modelo de recuperação completa. Tenha cuidado, porém, cada vez menor de bancos de dados geralmente não é aconselhável, e se você reduzir o modelo de recuperação de um banco de dados ao vivo que você está pedindo algo para dar errado.

Como alternativa, você poderia fazer uma mesa reconstrução completa para garantir que não está pendurado há dados extras em torno de qualquer lugar:

CREATE TABLE tmp_table(<column definitions>);
GO
INSERT INTO tmp_table(<columns>) SELECT <columns> FROM <table>;
GO
DROP TABLE <table>;
GO
EXEC sp_rename N'tmp_table', N'<table>';
GO

É claro, as coisas ficam mais complicadas com a identidade, índices, etc etc ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top