Il modo migliore per deframmentare / compattare un database per scopi di archiviazione


9

Abbiamo un'istanza di SQL Server utilizzata per l'archiviazione della posta elettronica (per gentile concessione di un pacchetto di archiviazione di terze parti). Ogni tanto, il software viene trasferito su un nuovo database vuoto. Lo abbiamo fatto trimestralmente in passato, ma ora stiamo cercando di farlo mensilmente. La quantità di dati archiviati è di circa 15-20 GB al mese e la maggior parte dei dati risiede solo in una manciata di tabelle (di solito 2 - 4).

Una volta passato a un nuovo database, quello vecchio viene utilizzato in modo strettamente di sola lettura. Quello che mi piacerebbe fare è ottimizzarlo in un file di dati bello e stretto, con tutte le tabelle / indici contigui e con un fattore di riempimento molto elevato, e non molto spazio vuoto alla fine del file di dati. Inoltre, stiamo usando Standard Edition su questo server, con tutte le limitazioni che ciò implica (altrimenti userei già la compressione dei dati).

Alcune possibilità che mi vengono in mente:

  1. RICOSTRUISCI / Riorganizza gli indici, DBCC SHRINKFILE (Okay, questa non è un'opzione sensata, dal momento che DBCC SHRINKFILE frammenterà il piscio da qualsiasi cosa tocchi, ma lo includo per completezza.)
  2. Crea un nuovo database con le statistiche automatiche disattivate. Script e ricrea tutte le tabelle dal database di origine. Utilizzare bcp per esportare / importare i dati nel nuovo database, in ordine di chiave cluster. Scrive e ricrea tutti gli indici. Ricalcola tutte le statistiche con la scansione completa.
  3. Crea un nuovo database con le statistiche automatiche disattivate. Script e ricrea tutte le tabelle dal database di origine. Utilizzare SSIS o T-SQL per trasferire i dati nel nuovo database. Scrive e ricrea tutti gli indici. Ricalcola tutte le statistiche con la scansione completa.

Il passaggio finale in ogni caso sarebbe impostare il database in modalità di sola lettura.

Quali altre opzioni buone / migliori ci sono per farlo? La mia preoccupazione è spostare i dati in modo tale da preservare un elevato fattore di riempimento e in modo logicamente contiguo.

Modificare:

Vorrei ricordare che circa il 75% dei dati sembra essere archiviato in colonne di immagini (LOB).


3
Ti interessa (o l'applicazione) se le tabelle finiscono fisicamente in un filegroup diverso da PRIMARY?
Jon Seigel,

@JonSeigel Suppongo di no, e in realtà è una buona idea, dato che mi risparmierebbe il problema di dover creare un database modello e spostare tutti i dati.
db2,

Stai considerando solo soluzioni che ti codificano o puoi anche esaminare alcune applicazioni per aiutarti? È possibile utilizzare SQL Storage Compress di RedGate per comprimere i dati in tempo reale. Oppure puoi provare Virtual Restore per rendere disponibili i backup compressi come dbs online (senza effettivamente disporre dello spazio completo necessario). Si basano tutti sul vecchio driver di file di Windows Hyperbac che è molto efficace nel comprimere dati e backup in tempo reale.
Marian,

@Marian Sembra interessante, ma per ora mi piacerebbe attenermi alle funzionalità native di SQL Server. Devo solo deframmentare molto efficacemente i database, senza lasciare molto spazio inutilizzato nei file. Se si tratta di uno strumento di terze parti che esegue il lavoro anziché lo scripting manualmente, va bene.
db2,

È solo un pensiero, ma perché non creare un nuovo filegroup, aggiungere un file, impostare una crescita ragionevole (diciamo 500 MB) e quindi ricostruire le tabelle su quel nuovo filegroup. Quindi ridurre il file principale fino a quasi nulla. Non ti preoccuperai della frammentazione delle tabelle di sistema.
Nic,

Risposte:


1

Per eliminare la frammentazione fisica nei file, è possibile spostare l'indice cluster con drop esistente in un nuovo filegroup. Poiché saranno RO, li rendono tutti fillfactor al 100% in quanto non è necessario spazio per gli inserti, le suddivisioni di pagina causate dagli aggiornamenti.

Ciò consentirebbe anche di eseguire un ripristino frammentario e di portare il database online molto rapidamente se si decide di passare all'Enterprise. Enterprise inoltre consente gli indici columnstore oltre a ridurre notevolmente il tempo di query per questi dati di sola lettura, che è un enorme raccordo.

È possibile utilizzare l'opzione shrinkfile una volta prima di passare alla lettura solo senza problemi seri con la frammentazione per rimuovere lo spazio alla fine del file come desiderato.

In una nota a margine, basta verificare che si stiano utilizzando gli ultimi tipi di dati per i tuoi LOBS. cioè nvarchar (max) o varchar (max) invece di ntext o text, varbinary (max) invece di image?


Sfortunatamente utilizza principalmente testo e immagini. È un'applicazione di terze parti, quindi non ho la possibilità di cambiarla.
db2

È davvero trasparente per l'applicazione, con il server SQL che archivia le informazioni in riga se <8k. Se il fornitore dice che non è supportato, chiederei loro perché stanno ancora utilizzando tipi di dati inizialmente deprecati in SQL Server 2005!
DamagedGoods

Non posso essere del tutto sicuro che l'applicazione non esegua operazioni specifiche di testo / immagine come WRITETEXT che fallirebbero dopo aver cambiato il tipo di dati. Ma tornando al punto principale, sembra che ricreare l'indice cluster non sposterà effettivamente i dati LOB con esso.
db2

puoi farlo ma devi entrare nel designer nella GUI, quindi espandere le proprietà, quindi hai uno 'spazio dati regolare' ma anche un filegroup TEXTIMAGE, cambiando questo, ma fai attenzione che ricrea la tabella! puoi ovviamente scrivere questo script ed eseguirlo in una finestra di manutenzione se possibile
DamagedGoods

Capito, potrebbe essere un modo utile per generare gli script di ricostruzione appropriati, almeno.
db2,

0

Ho riscontrato un problema simile con uno strumento di terze parti che utilizzava anche un tipo di dati immagine per archiviare dati non strutturati e l'ho risolto convertendo la colonna per utilizzare filestream . Dovrai eseguire alcuni test per assicurarti che l'app funzioni ancora come previsto, ma ciò ti darà la possibilità di scrivere il tuo processo di archiviazione che sposta i tuoi dati in un db di archivio in modo efficiente.


Ho il sospetto che il filestream non si ridimensionerebbe bene in questo caso. Abbiamo oltre 14 milioni di righe in 17 database e riceviamo messaggi a circa 15.000 al giorno. Una parte sostanziale dei corpi dei messaggi è inferiore a 4 KB, quindi lo spreco di cluster NTFS sarebbe probabilmente brutale (e questo anche se aggiungessimo un nuovo volume del disco con una dimensione del blocco inferiore a 64 KB).
db2

In tal caso, puoi convertire il tipo di dati in qualcosa come nvarchar (max) e utilizzare la clausola TEXTIMAGE_ON per specificare un filegroup diverso per questi oggetti di grandi dimensioni? Ciò ti consentirà di archiviare i dati fuori riga e di creare il tuo processo per gestire l'archiviazione.
Liam Confrey,

l'uso del filestream dipende davvero da quanto sono grandi i LOBS. Penso che> 1 MB per record da prendere in considerazione. Quindi sarei d'accordo in questo caso che non è un'opzione
DamagedGoods
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.