web-dev-qa-db-fra.com

Revendication d'espace disque après la suppression du champ de table

J'utilise sql 2008 r2 et la base de données fonctionnait bien et rapidement depuis 3 ans jusqu'à il y a environ 3 mois, nous avons ajouté le champ ntext sur une table très active et utilisée. Maintenant, nous commençons à manquer d'espace sur le serveur en raison de l'énorme taille croissante de cette table.

J'ai lu que rétrécissement, nous ne voulons pas perdre l'indexation de db parce qu'il fonctionnait rapidement pendant des années et nous ne voulons pas que la fragmentation se dilate.

Nous avons décidé de supprimer ce champ et toutes ses valeurs: Existe-t-il un moyen de supprimer le champ ntext et toutes ses valeurs et de libérer de l'espace sans supprimer l'indexation, sans rétrécir, sans perdre les performances db?

J'attache la sortie de la requête de taille db pour vous montrer l'expansion de la taille des 5 derniers mois.

enter image description here

16
user1021182

Nous avons décidé de supprimer ce champ et toutes ses valeurs: existe-t-il un moyen de supprimer le champ ntext et toutes ses valeurs et de libérer de l'espace sans supprimer l'indexation, sans rétrécir, sans perdre les performances db?

Je recommanderais d'utiliser (de BOL:)

DBCC CLEANTABLE
(
    { database_name | database_id | 0 }
    , { table_name | table_id | view_name | view_id }
    [ , batch_size ]
)
[ WITH NO_INFOMSGS ]

DBCC CLEANTABLE récupère de l'espace après la suppression d'une colonne de longueur variable. Une colonne de longueur variable peut être l'un des types de données suivants: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant et xml. La commande ne récupère pas d'espace après la suppression d'une colonne de longueur fixe.

!! [~ # ~] attention [~ # ~] !! (( utilisez une taille de lot prudente - il est conseillé d'utiliser ce paramètre si votre table est massive):

DBCC CLEANTABLE s'exécute comme une ou plusieurs transactions. Si une taille de lot n'est pas non spécifiée , la commande traite la table entière en une seule transaction et la table est exclusivement verrouillée pendant l'opération . Pour certaines grandes tables, la longueur de la transaction unique et l'espace journal requis peuvent être trop importants. Si une taille de lot est spécifiée, la commande s'exécute dans une série de transactions, chacune comprenant le nombre de lignes spécifié. DBCC CLEANTABLE ne peut pas être exécuté en tant que transaction dans une autre transaction.

Cette opération est entièrement enregistrée.

Une simple repro prouvera que DBCC CLEANTABLE vaut mieux que RÉTRÉCISSER (et pas de souci de fragmentation :-)

-- clean up
drop table dbo.Test

-- create test table with ntext column that we will drop later
create table dbo.Test (
    col1 int
    ,col2 char(25)
    ,col3 ntext
    );

-- insert  1000 rows of test data
declare @cnt int;

set @cnt = 0;

while @cnt < 1000
begin
    select @cnt = @cnt + 1;

    insert dbo.Test (
        col1
        ,col2
        ,col3
        )
    values (
        @cnt
        ,'This is a test row # ' + CAST(@cnt as varchar(10)) + 'A'
        ,REPLICATE('KIN', ROUND(Rand() * @cnt, 0))
        );
end

enter image description here

enter image description here

--drop the ntext column
ALTER TABLE dbo.Test DROP COLUMN col3 ;

enter image description here

enter image description here

--reclaim the space from the table
-- Note that my table is only having 1000 records, so I have not used a batch size
-- YMMV .. so find a maintenance window and you an appropriate batch size 
-- TEST TEST and TEST before implementing in PROD.. so you know the outcome !!
DBCC CLEANTABLE('tempdb', 'dbo.Test') ;

enter image description here

enter image description here

12
Kin Shah

Pour la plupart des parties, je fais référence à Paul Randall Inside the storage engine blog series.

La seule façon de récupérer l'espace inutilisé des fichiers de base de données dans SQLServer est d'utiliser la commande DBCC SHRINK qui réalloue les données dans les pages de libération des fichiers de base de données et après les avoir supprimées de la carte Global Allcation, les supprime du fichier de base de données. Cette opération est lente, crée une fragmentation au sein de la base de données et est encore plus lente lorsqu'il s'agit de pages LOB car celles-ci sont stockées sous forme de listes liées dans les fichiers de base de données.

Puisque vous supprimez la colonne NTEXT, vous devrez attendre que le processus de nettoyage fantôme supprime les données avant de rétrécir.

Maintenant, avoir beaucoup d'espace libre dans les fichiers de base de données ne vous fera aucun mal, si vous avez l'espace disque, la compression de sauvegarde prendra soin de l'espace libre dans les fichiers.

Si vous voulez absolument réduire la taille des fichiers, vous pouvez créer un nouveau groupe de fichiers avec la base de données et en faire la valeur par défaut, puis déplacer les tables dans le nouveau groupe de fichiers, mais cela peut prendre du temps et entraîner des temps d'arrêt. J'ai utilisé la technique expliquée ici par Bob Pusateri avec de bons résultats.

6
Spörri

Voulez-vous réduire les fichiers de base de données parce que vous avez besoin de cet espace pour d'autres bases de données/fichiers non DB ou parce que vous rencontrez des problèmes avec cette base de données à court d'espace?

Si c'est le deuxième, alors vous pourriez ne pas avoir un problème aussi important que vous le pensez. Si j'ai raison, votre problème est lorsque la base de données doit se développer pour gagner de l'espace supplémentaire pour de nouvelles données. Une fois que vous avez supprimé la colonne, tout l'espace occupé par cette colonne sera libéré pour que de nouvelles lignes soient ajoutées aux tables de la base de données. Cela signifie qu'il faudra plus de temps avant que votre base de données ait besoin de croître. En attendant, j'obtiendrais de l'espace supplémentaire pour votre lecteur de données. La plupart des bases de données se développent au fil du temps et il est agréable d'avoir une marge saine d'espace libre sur le disque.

4
Kenneth Fisher

Je voudrais créer une table miroir sans la colonne incriminée, copier toutes les données dans cette table, supprimer l'original, puis renommer la table miroir.

0
ardochhigh