Comment réduire la taille de la table SQL Server issue d'un changement de type de données

j'ai une table sur SQL Server 2005 qui était d'environ 4 Go de taille.

(environ 17 millions d'enregistrements)

j'ai changé l'un des champs de type de données char(30) à char(60) (il y a au total 25 champs dont la plupart sont char(10) donc la quantité d'espace de char s'élève à environ 300)

ce qui a causé la table de doubler dans la taille (plus de 9 Go)

j'ai alors changé le char(60) en varchar(60) et puis a couru une fonction pour couper les espaces supplémentaires hors des données (afin de réduire la longueur moyenne des données dans le domaine à environ 15)

cela n'a pas réduit la taille de la table. Rétrécir la base de données n'a pas aidé non plus.

sous peine de recréer la structure de la table et de copier les données au-dessus (c'est 17 millions d'enregistrements!) existe-t-il un moyen moins radical de redescendre la taille?

20
demandé sur Christopher Rapcewicz 2009-04-30 19:41:37

5 réponses

il est clair que vous ne récupérez pas d'espace ! :- )

quand vous avez changé vos champs de texte en CHAR(60), ils sont tous remplis à capacité avec des espaces. Donc tous vos champs sont maintenant en réalité 60 caractères.

changer cela en VARCHAR (60) ne va pas aider - les champs sont encore tous les 60 chars de long....

ce que vous avez vraiment besoin de faire est d'exécuter une fonction de finition sur tous vos champs pour les réduire de nouveau à leurs parés longueur, puis faire un rétrécissement de la base de données.

après avoir fait cela, vous devez reconstruire votre index groupé afin de récupérer une partie de cet espace gaspillé. L'indice clustered est vraiment l'endroit où vos données vivent - vous pouvez le reconstruire comme ceci:

ALTER INDEX IndexName ON YourTable REBUILD 

par défaut, votre clé primaire est votre index groupé (sauf indication contraire).

Marc

16
répondu marc_s 2009-04-30 18:14:42

vous n'avez pas nettoyé ou compacté de données, même avec une"base de données de rétrécissement".

DBCC CLEANTABLE

récupère de l'espace à partir de colonnes de longueur variable dans des tableaux ou des vues indexées.

Cependant, un simple reconstruction d'index si il y a un index cluster devrait aussi le faire

ALTER INDEX ALL ON dbo.Mytable REBUILD

exemple ouvré de Tony Rogerson

24
répondu gbn 2009-04-30 18:22:55

je sais que je ne réponds pas à votre question comme vous le demandez, mais avez-vous envisagé d'archiver certaines données dans une table d'historique, et de travailler avec moins de lignes?

La plupart du temps, vous pourriez penser à première vue que vous avez besoin de toutes ces données tout le temps, mais quand réellement assis et l'examiner, Il ya des cas où ce n'est pas vrai. Ou du moins, j'ai déjà vécu cette situation.

2
répondu JRL 2009-04-30 15:53:56

j'ai eu un problème similaire ici SQL Server, Conversion NTEXT de type NVARCHAR(MAX) qui a été liée à l'évolution de la ntext de type nvarchar(max).

j'ai dû faire un UPDATE MyTable SET MyValue = MyValue pour pouvoir tout redimensionner correctement.

cela prend évidemment beaucoup de temps avec beaucoup de disques. Un certain nombre de suggestions ont été faites quant à la meilleure façon de le faire. Il s'agissait d'un indicateur temporaire indiquant si cela avait été fait ou non et puis mettre à jour quelques milliers à la fois dans une boucle jusqu'à ce que tout soit fait. Cela signifiait que j'avais "un certain" contrôle sur tout ce qu'il faisait.

sur une autre note cependant, si vous voulez vraiment rétrécir la base de données autant que possible, il peut aider si vous tournez le modèle de récupération vers le bas à simple, rétrécir les journaux de transactions, réorganiser toutes les données dans les pages, puis le remettre au modèle de récupération complète. Attention cependant, rétrécir les bases de données n'est généralement pas conseillé, et si vous réduire le modèle de récupération d'une base de données que vous demandez quelque chose à aller mal.

0
répondu Robin Day 2017-05-23 11:46:18

alternativement, vous pouvez faire une reconstruction complète de la table pour s'assurer qu'il n'y a pas de données supplémentaires autour de n'importe où:

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

bien sûr, les choses se compliquent avec l'identité, les index, etc...

0
répondu thecoop 2009-04-30 15:59:35