En SQL Server es pot utilitzar l'ordre d'DBCC SHRINKDATABASE per reduir l'espai ocupat pels arxius de dades i de log d'una base de dades.

ShrinkDatabase de SQL Server

 

El problema que té SHRINKDATABASE és que, si no s'utilitza amb cura, pot donar com a resultat un important increment en la fragmentació dels índexs, i també de les taules, cosa que deriva en un empitjorament del rendiment de la nostra base de dades SQL Server, i fins i tot un augment de l'espai ocupat quan es reconstrueixin els índexs afectats per la fragmentació.

Què fa la comanda DBCC ShrinkDatabase

La comanda SHRINK allibera l'espai lliure que queda en els arxius de la base de dades, fent que en lloc de quedar reservat per al creixement de les dades, es 'retorni' al sistema operatiu. La reducció d'espai es produeix, però cal pensar en el creixement de la base de dades. Si no es deixa espai lliure contigu al que utilitza cada taula, les noves dades es crearan en diferents ubicacions físiques, s'augmentarà la fragmentació, i es complicaran els índexs i les ordenacions.

Incloure SHRINKDATABASE entre les operacions diàries de manteniment d'una BD SQLServer, per exemple, pot provocar un important problema de fragmentació, ja que les dades que s'inserissin podrien quedar emmagatzemats en una ubicació física diferent per a cada nou dia després l'execució del SHRINK.

Quan i com cal utilitzar Shrink en SQL Server

Però aleshores, SHRINK DATABASE serveix per a alguna cosa? Sí que serveix, en determinats casos. Si en una base de dades SQL Server s'eliminen o es trunquen taules, que redueixen considerablement el volum ocupat per les dades, i no hi ha previsió de tornar a ocupar aquest espai, pot interessar utilitzar per ajustar millor la relació entre espai ocupat i espai reservat, reduint així la mida de la base de dades, però sempre és recomanable deixar un percentatge d'espai lliure reservat tant per a les operacions diàries de la base de dades com per al creixement de les dades amb la mínima fragmentació.

En cas d'utilitzar el Shrink de SQLServer, per assegurar aquest espai reservat i que el creixement no impliqui problemes de fragmentació i rendiment, és important revisar els arguments que admet la comanda, ja que si s'informa el segon argument amb un nombre la reducció de espai es realitzarà deixant aquest nombre com a percentatge d'espai no utilitzat, que no es tornarà al sistema operatiu, i quedarà reservat pel creixement de les dades.

Sintaxi de la comanda

DBCC SHRINKDATABASE  
( database_name | database_id | 0      
          [ , target_percent ]      
          [ , { NOTRUNCATE | TRUNCATEONLY } ]  
)  
[WITH NO_INFOMSGS]

 

Exemple d'utilització de Shrink

Per exemple, si acabem de realitzar operacions de neteja (eliminar esquemes no utilitzats, taules temporals o simplement innecessàries) a la base de dades que sabem que han reduït l'espai ocupat per les dades en un 50%, i volem reduir l'espai ocupat per els fitxers de la base de dades, però deixant reservat un 15% d'espai lliure per a les operacions diàries, i per al creixement que preveiem de la base de dades per a l'any actual, podríem executar aquesta comanda:

DBCC SHRINKDATABASE (Mi_base_de_datos, 15);

D'aquesta manera l'espai ocupat pels fitxers de dades i de registre de la base de dades es reduiria aproximadament en un 35%. Si no incloguéssim el paràmetre del percentatge, reduiríem més l'espai, però l'endemà les noves insercions de dades ja començarien a necessitar ampliacions de mida dels fitxers que òbviament no es trobarien en el mateix espai físic que les dades existents, i augmentarien la fragmentació de les dades.

 

Recomanació per reduir la fragmentació

I ja que parlem de fragmentació, el que sí és recomanable incloure en les tasques de manteniment periòdiques és una reconstrucció dels índexs amb un REBUILD, cosa que reduirà la fragmentació i millorarà el rendiment de la DB, encara que pugui incrementar una mica més l'espai utilitzat:

ALTER INDEX idx_mitabla_ID ON MiTabla REBUILD;

 

Referències

Finalment, enllaço com a referència algunes entrades de bloc d'altres llocs que expliquen per què fer un Shrink Database normalment no és bona idea, aporten raons per no utilitzar un ShrinkDatabase, o que fan una demostració pràctica del que passa amb l'espai i la fragmentació en fer un ShrinkDatabase.

 

Coneixes algun cas més en què sigui o no recomanable fer un Shrink? T'has trobat en alguna ocasió un problema de fragmentació o de rendiment provocat per una desafortunada utilització de ShrinkDatabase?