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

16

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 que cela fonctionnait rapidement pendant des années et nous ne voulons pas que la fragmentation s'étende.

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.

entrez la description de l'image ici

user1021182
la source

Réponses:

12

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 aucune taille de lot n'est 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 CLEANTABLEc'est mieux que Rétrécir (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

entrez la description de l'image ici

entrez la description de l'image ici

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

entrez la description de l'image ici

entrez la description de l'image ici

--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') ;

entrez la description de l'image ici

entrez la description de l'image ici

Kin Shah
la source
Après avoir exécuté la commande DBCC CLEANTABLE, vous devez RECONSTRUIRE votre index clusterisé au cas où la table en aurait un, afin de récupérer l'espace. ALTER INDEX IndexName ON YourTable REBUILD;
Monsieur TA
6

Pour la plupart des parties, je fais référence à la série de blogs Inside the storage engine de Paul Randall .

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.

Spörri
la source
le processus de nettoyage des fantômes réduira-t-il l'espace ou le rétrécissement sera-t-il également nécessaire?
user1021182
vous devrez toujours réduire, Le processus de nettoyage ne vide que les pages allouées mais ne les supprime pas des fichiers de la base de données
Spörri
1
@ Spörri Since you are dropping the NTEXT column you will have to wait for the ghost cleanup process to drop the data before shrinking.Veuillez voir ma réponse . Vous pouvez utiliser DBCC CLEANTABLEpour libérer l'espace.
Kin Shah
4

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 avec le temps et il est agréable d'avoir une marge saine d'espace libre sur le disque.

Kenneth Fisher
la source
il ne nous reste que 10 Go d'espace disque et il s'épuisera également dans quelques jours. nous avons supprimé tout ce que nous pouvions supprimer du serveur et utilisé des nettoyages et arrêté les mises à jour de Windows et les avons tous corrigés et nettoyé les winsxs, nous devons maintenant réduire la taille du fichier db
user1021182
Encore une fois, n'oubliez pas qu'une fois que vous avez supprimé la colonne supplémentaire, la croissance de votre base de données s'arrêtera pendant un certain temps pendant que vous remplissez le nouvel espace que vous avez libéré. Si votre base de données continue de croître après ce point, vous aurez absolument besoin d'espace disque supplémentaire pour votre base de données. Ajoutez éventuellement un nouveau lecteur à votre serveur.
Kenneth Fisher du
0

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.

ardochhigh
la source
dans ce cas, tous les index devront également être préparés
user1021182
oui, tous les index affectant la table devront être supprimés et recréés également .... s'applique également aux autres objets référençant la table, par exemple: triggers
ardochhigh