Reconstruction des index, DB maintenant 10 fois la taille

13

J'ai une base de données SQL Server (2008 R2 SP1) qui faisait environ 15 concerts. Il s'avère que la maintenance n'avait pas été exécutée depuis un certain temps, j'ai donc créé un plan de maintenance pour reconstruire tous les index, ils étaient très fragmentés.

Le travail est terminé et la fragmentation a disparu, mais maintenant la base de données compte plus de 120 concerts! Je comprends qu'il aurait utilisé de l'espace supplémentaire pour faire toutes les reconstructions, mais maintenant que le travail est terminé, je pense que tout cet espace serait de l'espace libre, mais l'espace libre n'apparaît que comme 3 concerts, donc 117 concerts sont utilisés même si la tâche de reconstruction d'index est terminée.

Je suis très confus et je pourrais utiliser quelques conseils, j'ai le retour à une taille raisonnable, nous n'avons pas l'espace disque pour cela.

Merci d'avance!

Voici les résultats des deux requêtes publiées:

log_reuse_wait_desc RIEN

name    TotalSpaceInMB  UsedSpaceInMB   FreeSpaceInMB
LIVE_Data   152             123             28
LIVE_Log    18939           89              18849
LIVE_1_Data 114977          111289          3688

Le 3ème fichier est un fichier .ndf, c'est celui qui n'affiche que 3688 dans l'espace inutilisé, mais 111289 pour environ 15 Go de données.

AS2012
la source

Réponses:

15

En attendant, je viens de comprendre cela, le rot du cerveau total. J'avais indiqué ce que je pensais être un facteur de remplissage de 90 dans le travail de reconstruction, mais il est libellé comme "changer le pourcentage d'espace libre en" donc en utilisant une valeur de 90, j'utilisais en fait un facteur de remplissage de 10 !! DOH. Pas étonnant qu'il soit 10 fois plus gros. Je vais reconstruire avec le bon facteur de remplissage puis rétrécir. Merci à tous pour votre contribution.

AS2012
la source
1
Cet assistant est tout simplement horrible.
usr
Je sais, je suis tellement habitué à la ligne de commande où vous spécifiez FILL_FACTOR et non% libre, j'aimerais que ce soit cohérent.
Ne réindexez pas puis rétrécissez, c'est juste une perte de temps! Voir ma réponse pour plus d'informations.
JNK
1
JNK Je sais ce que tu veux dire par ne pas rétrécir après une reconstruction car cela va tout fragmenter à nouveau. Cependant, dans ce scénario particulier où Jeff par accident a ajouté 90% d'espace libre à chaque page, je ne vois pas d'autre moyen de récupérer l'espace ensuite: reconstruire avec fillfactor 90, réduire le fichier, mais vous devrez faire une autre reconstruction avec fillfactor 90% à nouveau. Ou y aurait-il une autre façon de récupérer l'espace. (Eh bien, peut-être un nouveau groupe de fichiers, puis reconstruisez
-le en le déposant
2

La reconstruction des index entraîne un espace libre supplémentaire dans la base de données. Il s'agit d'un sous-produit naturel du processus de réindexation - le serveur crée une nouvelle version, espérons-le, contiguë de l'index à côté de la version actuelle, puis supprime la version actuelle une fois terminée.

Rétrécir après avoir réindexé est inutile!

Vous allez juste re-fragmenter l'index! La réduction supprime l'espace libre en réallouant les données dans la base de données.

Voici un bel article de Paul Randal, qui, lorsqu'il travaillait chez Microsoft, était en charge du DBCCcode, y compris les rétrécissements, sur les raisons pour lesquelles vous ne devriez pas rétrécir.

JNK
la source
0

Vous devriez avoir utilisé l'option de reconstruction SORT_IN_TEMPDB=ON.

Dans votre cas, le ou les fichiers de données réels, où se trouvent les tables en question, ont été utilisés pour trier les index. Une grande partie de cet espace de 120 Go n'est pas encore utilisée et sera remplie de données de page en cas de besoin.

Vous pouvez voir l'état de l'espace utilisé / libre avec cette requête (prise à partir d' ici ):

use [YourDatabaseNameHere]
go

select
    name,
    cast((size/128.0) as int) as TotalSpaceInMB,
    cast((cast(fileproperty(name, 'SpaceUsed') as int)/128.0) as int) as UsedSpaceInMB,
    cast((size/128.0 - cast(fileproperty(name, 'SpaceUsed') AS int)/128.0) as int) as FreeSpaceInMB
from
    sys.database_files

Pour réduire un fichier de base de données spécifique (données ou journal), vous pouvez voir quelques informations ici . Un avertissement avant cela, libérer de l'espace inutilisé prend un certain temps pour les bases de données 100+ Gb (dépend également de la vitesse de stockage), alors laissez-le fonctionner.

Marcel N.
la source
OUI ça ne sera pas formaté, je vais l'ajouter à la question, un instant.
@JeffBane: Pouvez-vous ajouter ces informations à votre question, dans un devis? Je ne vois pas ce qu'il y a dedans.
Marcel N.
1
Lors de la reconstruction d'un index, vous auriez besoin du double de l'espace de l'index + 20% pour le tri. Donc, en général, pour reconstruire chaque index de votre base de données, vous n'avez besoin que de 120% de votre plus grand index dans votre base de données. Si vous utilisez SORT_IN_TEMPDB, vous ne gagnez que 20%, vous avez encore besoin d'un 100% supplémentaire dans votre fichier de données. De plus, l'utilisation de sort dans tempdb augmente considérablement votre charge d'E / S, car au lieu d'écrire une fois l'index dans le fichier de données, vous l'écrivez maintenant une fois dans la tempdb, puis l'écrivez dans le fichier de données. Ce n'est donc pas toujours idéal.
Edward Dortland
-1

Sans aucun autre détail, je soupçonne que vous devez effectuer une sauvegarde du journal des transactions avant de pouvoir récupérer son espace.

Voyez ce qui select name, log_reuse_wait_desc from sys.databasesvous dit. Si la colonne log_reuse_wait_desc l'indique, LOG_BACKUPelle ne peut pas récupérer d'espace tant que vous n'avez pas effectué une sauvegarde du journal de transfert.

dpw
la source
La nécessité de faire une sauvegarde du journal des transactions n'entraînerait jamais la libération de pages.
mrdenny