Richiesta di spazio su disco dopo la rimozione del campo tabella


16

Sto eseguendo sql 2008 r2 e il db funzionava bene e velocemente negli ultimi 3 anni fino a circa 3 mesi fa abbiamo aggiunto il campo ntext su una tabella molto attiva e usata. Ora stiamo iniziando a uscire dallo spazio del server a causa delle enormi dimensioni in espansione di questa tabella.

Ho letto che restringendo, non vogliamo perdere l'indicizzazione di db perché ha funzionato velocemente per anni e non vogliamo che la frammentazione si spenda.

Abbiamo deciso di eliminare quel campo e tutti i suoi valori: esiste un modo per eliminare il campo ntext e tutti i suoi valori e liberare spazio senza rimuovere l'indicizzazione, senza ridurre, senza perdere le prestazioni del db?

Vi allego l'output della query sulla dimensione db per mostrarvi l'espansione della dimensione degli ultimi 5 mesi.

inserisci qui la descrizione dell'immagine

Risposte:


12

Abbiamo deciso di eliminare quel campo e tutti i suoi valori: esiste un modo per eliminare il campo ntext e tutti i suoi valori e liberare spazio senza rimuovere l'indicizzazione, senza ridurre, senza perdere le prestazioni del db?

Consiglierei di usare (da BOL:)

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

DBCC CLEANTABLE recupera lo spazio dopo l'eliminazione di una colonna di lunghezza variabile. Una colonna a lunghezza variabile può essere uno dei seguenti tipi di dati: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant e xml. Il comando non recupera lo spazio dopo l'eliminazione di una colonna di lunghezza fissa.

!! ATTENZIONE !! ( usa una dimensione batch attenta : è consigliabile utilizzare questo parametro se la tabella è enorme) :

DBCC CLEANTABLE viene eseguito come una o più transazioni. Se non viene specificata una dimensione batch , il comando elabora l'intera tabella in una transazione e la tabella viene bloccata esclusivamente durante l'operazione . Per alcune tabelle di grandi dimensioni, la lunghezza della singola transazione e lo spazio di log richiesto potrebbero essere eccessivi. Se viene specificata una dimensione batch, il comando viene eseguito in una serie di transazioni, ciascuna delle quali include il numero specificato di righe. DBCC CLEANTABLE non può essere eseguito come transazione all'interno di un'altra transazione.

Questa operazione è completamente registrata.

Una semplice riproduzione dimostrerà che DBCC CLEANTABLEè meglio di SHRINKING (e non preoccuparti della frammentazione :-)

-- 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

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


Dopo aver eseguito il comando DBCC CLEANTABLE, è necessario RICOSTRUIRE l'indice cluster nel caso in cui la tabella ne abbia uno, al fine di recuperare lo spazio. INDICE ALTER IndexName ON YourTable REBUILD;
Mr. TA

6

Per la maggior parte mi riferisco alla serie di blog Inside the engine del motore di archiviazione di Paul Randall .

L'unico modo per recuperare spazio inutilizzato dai file di database in SQL Server è utilizzare il comando DBCC SHRINK che rialloca i dati all'interno dei file di database liberando le pagine e dopo averli rimossi dalla mappa Global Allcation li rimuove dal file di database. Questa operazione è lenta, crea frammentazione all'interno del database ed è ancora più lenta quando si tratta di pagine LOB in quanto queste sono archiviate come elenchi collegati all'interno dei file del database.

Dato che stai lasciando cadere la colonna NTEXT, dovrai aspettare che il processo di pulizia del fantasma elimini i dati prima di ridurli.

Ora avere un sacco di spazio libero nei file del database non ti farà davvero del male, se hai lo spazio su disco, la compressione di backup si occuperà dello spazio libero all'interno dei file.

Se si desidera assolutamente ridurre i file, è possibile creare un nuovo filegroup con il database e renderlo predefinito e quindi spostare le tabelle nel nuovo filegroup, ma ciò può richiedere tempo e causare tempi di inattività. Ho usato la tecnica spiegata qui da Bob Pusateri con buoni risultati.


il processo di pulizia dei fantasmi ridurrà lo spazio o si ridurrà anche?
user1021182

dovrai sempre restringere, Il processo di pulizia svuota solo le pagine allocate ma non le rimuove dai file del database
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.Vedi la mia risposta . È possibile utilizzare DBCC CLEANTABLEper liberare lo spazio.
Kin Shah,

4

Vuoi ridurre i file del database perché hai bisogno di quello spazio per altri database / file non DB o perché stai riscontrando problemi con questo database a corto di spazio?

Se è il secondo, potresti non avere un problema così grande come pensi. Se ho ragione, il tuo problema è quando il database deve crescere per guadagnare spazio aggiuntivo per i nuovi dati. Una volta rimossa la colonna, tutto lo spazio occupato da quella colonna verrà liberato per le nuove righe da aggiungere alle tabelle nel database. Ciò significa che ci vorrà più tempo prima che il database debba crescere. Nel frattempo avrei avuto un po 'di spazio aggiuntivo per il tuo disco dati. La maggior parte dei database cresce nel tempo ed è bello avere un buon margine di spazio libero sull'unità.


abbiamo solo 10 GB di spazio su disco e si esaurirà anche in pochi giorni. abbiamo rimosso tutto ciò che potevamo rimuovere dal server e usato cleanup e fermato gli aggiornamenti di Windows e li abbiamo rimossi tutti e ripuliti i winsxs, ora dobbiamo ridurre le dimensioni del file db
user1021182

Ancora una volta, ricorda che una volta eliminata la colonna aggiuntiva, la crescita del tuo DB si fermerà per un po 'mentre riempi il nuovo spazio che hai liberato. Se il tuo DB continua a crescere dopo questo punto, avrai assolutamente bisogno di spazio su disco aggiuntivo per il tuo database. Aggiungi eventualmente una nuova unità al tuo server.
Kenneth Fisher,

0

Vorrei creare una tabella mirror senza la colonna offensiva, copiare tutti i dati in questa tabella, eliminare l'originale e quindi rinominare la tabella mirror.


in tal caso sarà necessario preparare anche tutti gli indici
user1021182

sì, tutti gli indici che influenzano la tabella dovranno essere eliminati e ricreati anche .... si applica anche ad altri oggetti che fanno riferimento alla tabella, ad esempio: trigger
ardochhigh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.