Meilleur moyen de défragmenter / compacter une base de données à des fins d'archivage

9

Nous avons une instance SQL Server utilisée pour l'archivage des e-mails (gracieuseté d'un package d'archivage tiers). De temps en temps, le logiciel est transféré dans une nouvelle base de données vide. Nous l'avons fait tous les trimestres dans le passé, mais nous envisageons de le faire tous les mois maintenant. La quantité de données archivées est d'environ 15 à 20 Go par mois et la majeure partie des données ne réside que dans une poignée de tableaux (généralement 2 à 4).

Une fois que nous sommes passés à une nouvelle base de données, l'ancienne devient utilisée en lecture seule. Ce que je voudrais faire, c'est l'optimiser en un joli fichier de données serré, avec toutes les tables / index contigus et ayant un facteur de remplissage très élevé, et pas beaucoup d'espace vide à la fin du fichier de données. De plus, nous utilisons Standard Edition sur ce serveur, avec toutes les limitations que cela implique (sinon j'utiliserais déjà la compression de données).

Quelques possibilités auxquelles je peux penser:

  1. RECONSTRUIRE / RÉORGANISER les index, DBCC SHRINKFILE (D'accord, ce n'est pas une option raisonnable, car DBCC SHRINKFILE fragmentera l'urine de tout ce qu'il touche, mais je l'inclus pour être complet.)
  2. Créez une nouvelle base de données avec désactivation des statistiques automatiques. Script et recréez toutes les tables de la base de données source. Utilisez bcp pour exporter / importer les données dans la nouvelle base de données, dans l'ordre des clés de cluster. Script et recrée tous les index. Recalculez toutes les statistiques avec une analyse complète.
  3. Créez une nouvelle base de données avec désactivation des statistiques automatiques. Script et recréez toutes les tables de la base de données source. Utilisez SSIS ou T-SQL pour transférer des données vers la nouvelle base de données. Script et recrée tous les index. Recalculez toutes les statistiques avec une analyse complète.

La dernière étape dans chaque cas serait de mettre la base de données en mode lecture seule.

Quelles sont les autres bonnes / meilleures options pour ce faire? Ma préoccupation est de déplacer les données de manière à préserver un facteur de remplissage élevé et de manière logiquement contiguë.

Éditer:

Je dois mentionner qu'environ 75% des données semblent être stockées dans des colonnes d'image (LOB).

db2
la source
3
Est-ce que vous (ou l'application) vous souciez si les tables se retrouvent physiquement dans un groupe de fichiers autre que PRIMARY?
Jon Seigel
@JonSeigel Je suppose que non, et en fait c'est une assez bonne idée, car cela m'éviterait d'avoir à créer une base de données de modèles et à déplacer toutes les données.
db2
Envisagez-vous uniquement des solutions que vous codez vous-même ou vous pouvez également examiner certaines applications pour vous aider avec cela? Vous pouvez utiliser SQL Storage Compress de RedGate pour compresser des données en direct. Ou vous pouvez essayer Virtual Restore pour rendre les sauvegardes compressées disponibles en tant que dbs en ligne (sans avoir réellement l'espace complet nécessaire). Ils sont tous basés sur l'ancien pilote de fichier Windows Hyperbac qui est très bon pour compresser les données en direct et les sauvegardes.
Marian
@Marian Semble intéressant, mais je voudrais m'en tenir aux capacités natives de SQL Server pour l'instant. J'ai juste besoin de défragmenter très efficacement les bases de données, sans beaucoup d'espace inutilisé dans le (s) fichier (s). Si c'est un outil tiers qui effectue le travail au lieu de créer des scripts manuellement, c'est bien.
db2
C'est juste une idée, mais pourquoi ne pas créer un nouveau groupe de fichiers, ajouter un fichier, définir une croissance raisonnable (disons 500 Mo), puis reconstruire vos tables sur ce nouveau groupe de fichiers. Réduisez ensuite le fichier principal à presque rien. Vous ne vous soucierez pas d'un coup de langue sur la fragmentation sur les tables système.
Nic

Réponses:

1

Pour éliminer la fragmentation physique des fichiers, vous pouvez aussi déplacer l'index cluster avec drop existant vers un nouveau groupe de fichiers. Comme ils vont être RO, faites-les tous 100% à 100% car aucun espace n'est nécessaire pour les insertions, les divisions de page causées par les mises à jour.

Cela vous permettrait également d'effectuer une restauration fragmentaire et de mettre la base de données en ligne très rapidement si vous décidiez de passer à Enterprise. Enterprise permet également des index columnstore en plus de réduire massivement le temps de requête pour ces données en lecture seule, qui est un congé massif.

Vous pouvez utiliser l'option de rétrécissement une fois avant de passer en lecture seule sans aucun problème sérieux de fragmentation pour supprimer l'espace à la fin du fichier comme vous le souhaitez.

Sur une note latérale, il suffit de vérifier que vous utilisez les derniers types de données pour votre LOBS. c'est-à-dire nvarchar (max) ou varchar (max) au lieu de ntext ou text, varbinary (max) au lieu d'image?

Marchandises endommagées
la source
Malheureusement, il utilise principalement du texte et des images. C'est une application tierce, donc je n'ai pas la possibilité de changer cela.
db2
@it vraiment transparent pour l'application, avec SQL Server stockant les informations dans la ligne si <8k. Si le fournisseur dit qu'il n'est pas pris en charge, je leur demanderais pourquoi ils utilisent toujours des types de données à l'origine déconseillés dans SQL Server 2005!
DamagedGoods
Je ne peux pas être totalement certain que l'application ne fait pas de choses spécifiques au texte / à l'image comme WRITETEXT qui échoueraient après avoir changé le type de données. Mais revenons au point principal, il semble que recréer l'index cluster ne déplace pas réellement les données LOB avec.
db2
vous pouvez le faire mais vous devez entrer dans le concepteur dans l'interface graphique, puis développer les propriétés, puis vous avez un 'espace de données régulier' mais aussi un groupe de fichiers TEXTIMAGE, en changeant cela, mais attention cela recréera la table! vous pouvez évidemment l'écrire et l'exécuter dans une fenêtre de maintenance si possible
DamagedGoods
J'ai compris, cela pourrait être un moyen utile de générer les scripts de reconstruction appropriés, à tout le moins.
db2
0

J'ai rencontré un problème similaire avec un outil tiers qui utilisait également un type de données d'image pour stocker des données non structurées, et je l'ai résolu en convertissant la colonne pour utiliser filestream . Vous devrez faire des tests pour vous assurer que l'application fonctionne toujours comme prévu, mais cela vous donnera la possibilité d'écrire votre propre processus d'archivage qui déplace vos données vers une base de données d'archive de manière efficace.

Liam Confrey
la source
Je soupçonne que le filestream n'évoluerait pas bien dans ce cas. Nous avons plus de 14 millions de lignes dans 17 bases de données et nous recevons des messages à environ 15 000 par jour. Une partie substantielle des corps de message est inférieure à 4 Ko, donc le gaspillage de cluster NTFS serait probablement brutal (et c'est même si nous ajoutons un nouveau volume de disque avec une taille de bloc inférieure à 64 Ko).
db2
Dans ce cas, pouvez-vous convertir le type de données en quelque chose comme nvarchar (max) et utiliser la clause TEXTIMAGE_ON pour spécifier un groupe de fichiers différent pour ces gros objets? Cela vous permettra de stocker les données hors ligne et de créer votre propre processus pour gérer l'archivage.
Liam Confrey
l'utilisation de filestream dépend vraiment de la taille de chacun des LOBS. Je pense que> 1 Mo par enregistrement à considérer. Donc je suis d'accord dans ce cas ce n'est pas une option
DamagedGoods