Quando è corretto ridurre un database?


43

So che il diavolo si restringe: inverte l'ordine delle pagine ed è responsabile del cancro della pelle, della frammentazione dei dati e del riscaldamento globale. L'elenco potrebbe continuare ... Detto questo, suppongo di avere un database da 100 GB e di eliminare 50 GB di dati, non su una tabella, ma una potatura generale di vecchi dati a livello di ampio database, coprendo il 90% del tabelle - costituisce un caso d'uso appropriato per ridurre il database?

In caso contrario, quali sono le misure appropriate da adottare per pulire la casa dopo aver rimosso una percentuale così elevata di dati da un database? Posso pensare a due: Ricostruisci gli indici e aggiorna le statistiche. Cos'altro?

Risposte:


13

Una riorganizzazione e riduzione non è mai davvero raccomandata.

Se riesci a portare offline le app che il database sta servendo, puoi velocizzare il processo e ridurre la frammentazione degli indici rimuovendo tutti gli indici e i vincoli di chiave primaria / esterna prima della riduzione (ciò significa che ci sono meno dati da spostare in quanto solo il le pagine di dati verranno mescolate non le pagine di indice ora inesistenti, accelerando il processo), quindi ricreano tutti gli indici e le chiavi.

Ricreare gli indici dopo la riduzione significa che non dovrebbero essere frammentati in modo significativo, e averli spariti durante la riduzione significa che ricostruirli non lascerà molti piccoli "buchi" nell'allocazione della pagina all'interno dei file che potrebbero invitare la frammentazione in un secondo momento.

Un'altra opzione se è possibile offline le applicazioni è migrare tutti i dati su un nuovo database della stessa struttura. Se il tuo processo di compilazione è solido, dovresti essere in grado di creare rapidamente quel DB vuoto, se non crearne uno dal DB corrente (ripristinare un backup di quello corrente, troncare / eliminare tutto il contenuto delle tabelle ed eseguire una riduzione completa).

Potresti comunque voler eliminare tutti gli indici nella destinazione e ricrearli in seguito poiché ciò può essere molto più efficiente quando si modificano molti dati indicizzati (in questo caso il 100%). Per accelerare il processo di copia, disporre i file di dati del database di destinazione su diverse unità fisiche all'origine (a meno che non si utilizzino SSD nel qual caso non è necessario preoccuparsi di ridurre i movimenti della testa), è possibile spostarli alla posizione di origine quando hai finito.

Inoltre, se si crea la destinazione come nuova (anziché cancellando una copia della fonte) crearla con una dimensione iniziale che conterrà tutti i dati correnti più alcuni mesi di crescita - ciò renderà i dati una copia un po 'più veloce come non assegnerà nuovo spazio ogni tanto durante il processo.

Questo potrebbe essere meglio dell'uso della riduzione perché la migrazione dei dati a un nuovo database replica l'azione prevista dell'operazione di riduzione, ma potenzialmente con una frammentazione molto inferiore (che è la conseguenza non intenzionale di una riorganizzazione e riduzione). Un restringimento prende semplicemente i blocchi dalla fine del file e li mette nel primo spazio più vicino all'inizio senza fare sforzi per mantenere insieme i dati correlati.

Ho il sospetto che il risultato sarà anche più efficiente in termini di spazio in quanto in seguito ci saranno probabilmente meno pagine parzialmente utilizzate. Un restringimento sposta semplicemente le pagine parzialmente utilizzate, spostando i dati è più probabile che si traducano in pagine intere soprattutto se si inserisce nella destinazione nell'ordine della chiave / indice cluster di una tabella (dove una tabella ne ha una) e crea altri indici dopo che tutti i dati sono stati migrati.

Ovviamente se non riesci a portare offline le app, eseguire solo una riduzione è la tua unica opzione, quindi se hai davvero bisogno di recuperare lo spazio vai con quello. A seconda dei dati, dei modelli di accesso, delle dimensioni comuni del set di lavoro, della quantità di RAM del server e così via, la frammentazione interna aggiuntiva potrebbe non essere poi così significativa alla fine.

Per l'operazione di copia, SSIS o T-SQL di base funzionerebbero altrettanto bene (l'opzione SSIS potrebbe essere meno efficiente, ma potenzialmente più facile da mantenere in seguito). Se crei le relazioni FK alla fine insieme agli indici, puoi fare un semplice "per ogni tabella, copia" in entrambi i casi. Naturalmente per una volta, una riduzione + riorganizzazione probabilmente va bene, ma mi piace solo spaventare le persone affinché non prendano mai in considerazione le riduzioni regolari! (Ho conosciuto gente programmarli tutti i giorni).


16

Il database tornerà a crescere? In tal caso, lo sforzo che farai nelle operazioni di riduzione sarà solo uno spreco, perché quando hai le dimensioni del file giù e poi aggiungi più dati, il file dovrà solo crescere di nuovo, e le transazioni devono attendere che avvenga tale crescita. Se hai impostazioni di crescita automatica non ottimali e / o una guida lenta, questa attività di crescita sarà abbastanza dolorosa.

Se si riduce il database, a che cosa serve lo spazio su disco liberato? Ancora una volta, se hai intenzione di mantenere questo spazio libero nel caso in cui questo database cresca di nuovo, allora stai solo facendo girare le ruote.

Quello che potresti considerare di fare, ora che hai tutto questo spazio libero nel file, è ricostruire i tuoi indici in modo che siano ottimizzati meglio (e sarà molto meno doloroso farlo quando hai spazio libero per farlo - pensa a provare a cambiare un maglione in un piccolo armadio contro una grande camera da letto).

Quindi, a meno che questa non sia stata un'operazione di pulizia importante e in realtà non aumenterai di nuovo lo stesso livello di dati, la lascerei così com'è e mi concentrerò su altre aree di ottimizzazione.


@Aarron Bertrand Beh, ci sono voluti 10 anni per diventare così grandi e il disco è un po 'preoccupante perché mi piacerebbe metterlo su stato solido. Stavo pensando di ridurlo a 60 GB con una crescita automatica da 5 GB. Davvero l'unica cosa che consiglieresti sarebbe ricostruire gli indici, eh? Pensavo che le persone avrebbero avuto qualche consiglio in più.
bumble_bee_tuna

E consiglierei la ricostruzione solo se ne hanno bisogno. Ma lo farei prima di ridurre il file. Non riesco davvero a pensare a niente di eccezionale che potresti fare con un po 'di spazio libero che fornirebbe ottimizzazioni delle prestazioni nel caso generale ...
Aaron Bertrand

2

Se stai esaurendo lo spazio e i tuoi dati non dovrebbero diventare così grandi, allora riduci, ma ricostruisci gli indici dopo con i fattori di riempimento appropriati che consentono una crescita tipica.

Se il tuo obiettivo finale è effettivamente quello di ridurre le dimensioni del backup assicurati di implementare una strategia di backup completa per cancellare il registro delle transazioni e quando esegui il backup del db, usa le opzioni di compressione.

Non consiglierei una crescita automatica di 5 GB a meno che in genere non ti aspetti di crescere frequentemente di 5 GB. In caso contrario, potrebbero verificarsi problemi di prestazioni intermittenti. Le dimensioni dei tuoi dati dovrebbero prima essere impostate su ciò che ritieni necessario per, diciamo, per un anno e Auto Growth dovrebbe essere impostato su una dimensione che hai testato non influisce sulle prestazioni operative. Vedi Non toccare quel pulsante Riduci database in SQL Server! di Mike Walsh.

La ricostruzione degli indici prima del restringimento causa una disposizione errata degli indici. Non è bene ricostruire e poi ridursi. Il restringimento fa sì che gli indici vengano mutilati per recuperare spazio, quindi ricostruire in anticipo e poi restringere è inutile. Vedi Quando utilizzare Auto Shrink di Thomas LaRock.


Se si riduce e quindi si ricostruiscono gli indici, il file di dati dovrà semplicemente crescere di nuovo per accogliere la copia dei dati utilizzati per la ricostruzione. Anche se in questo caso non sarà grande come il file di dati originale, sarà comunque in crescita e sembrerà controproducente. Ricostruire mentre c'è spazio libero sarà più veloce (non è necessaria la crescita automatica) e sarà generalmente migliore di quanto tu suggerisca su come delinea le pagine per la nuova copia dell'indice, e sospetto che nella maggior parte dei casi questo sarà complessivamente più breve e portare allo stesso o migliore recupero dello spazio su disco. Forse tempo per alcuni test.
Aaron Bertrand

E, naturalmente, questo presuppone che gli indici sui dati che resteranno dovranno effettivamente essere ricostruiti - forse sono già in buona forma.
Aaron Bertrand

1

Non so se questo avrebbe funzionato meglio della reindicizzazione dopo la riduzione, ma un'altra opzione sarebbe quella di creare un nuovo file di dati di dimensioni adeguate e spostare tutti i dati in quello. In quel caso farei prima un reindex in modo da sapere qual è la dimensione effettiva dei dati. Un problema è che se questo è il primo file nel file di dati primario non penso che tu possa svuotarlo. Dovresti essere in grado di ridurlo, quindi spostare nuovamente i dati in seguito e ciò eviterebbe l'inversione della pagina. Tuttavia, se stai cercando di passare allo stato solido, ciò non dovrebbe fare comunque una grande differenza.


1

Tornando a questo MODO in ritardo. Tuttavia, abbiamo riflettuto e testato anche l'uso del restringimento nei nostri ambienti di test per molto tempo. Come per l'argomento, ci sono momenti in cui la riduzione è un'opzione praticabile. Ma sapere quando e come applicarlo, è vitale per una corretta esecuzione sia a lungo che a breve termine.

Nel nostro scenario, abbiamo recentemente aggiunto numerose modifiche al nostro ampio DB tra cui compressione, partizionamento, archiviazione e semplice cancellazione dei dati ridondanti. Di conseguenza, la parte utilizzata del nostro file di dati primario è scesa a meno della metà rispetto a prima. Ma che senso ha trasportare tutto quel bagaglio? Soprattutto perché contrariamente ad alcuni articoli sul Web, la dimensione dei file di dati CORRELA DIRETTAMENTE CON DURATA DEL BACKUP / RIPRISTINO. Questo perché, a differenza di molti articoli, gli scenari di vita reale hanno molti più dati su una determinata pagina rispetto alle cose che potresti aver rimosso.

Più precisamente, questo apre un ottimo scenario per la riduzione:

  1. Crea uno script che troverà tutti gli oggetti e i relativi filegroup nel tuo database (molti esempi online), utilizzalo per creare le clausole di rilascio e creare definizioni per ciascuno dei tuoi indici e vincoli.
  2. Crea un nuovo file e filegroup e impostalo come predefinito.
  3. Elimina tutti gli indici non cluster (nota, alcuni indici possono essere vincoli).
  4. Crea i tuoi indici cluster sul nuovo filegroup con DROP_EXISTING = ON (che, a proposito, è un'operazione immensamente veloce, minimamente registrata, per cominciare rispetto a molte alternative).
  5. Ricrea i tuoi indici non cluster.
  6. Infine, SHRINK il tuo vecchio file di dati (di solito PRIMARY).

In questo modo gli unici dati rimasti lì sarebbero gli oggetti di sistema, le statistiche, le procedure del tuo DB e quant'altro. La riduzione dovrebbe essere molto, MOLTO più veloce e non è necessario alcun ulteriore mantenimento dell'indice sui tuoi oggetti dati principali che saranno stati creati in modo ordinato e rischi minimi per la frammentazione futura.

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.