web-dev-qa-db-fra.com

La fragmentation d'index a augmenté de manière significative après la reconstruction

J'ai googlé cela et je sais que certaines personnes disent que la fragmentation de l'index n'a pas d'importance, mais ils vont décrire des scénarios où cela pourrait importer. La mienne pourrait être un tel scénario.

J'ai un index sur une énorme table (86 millions de lignes) d'environ 33% fragmentés.

Il y a quelques jours, j'ai commencé à remarquer certaines requêtes prenaient trop de temps. Il semblait qu'ils n'utilisaient pas l'un des index, même si les requêtes sont écrites de manière à utiliser l'index (je pouvais me tromper à propos de l'index non utilisé)

Donc, une des choses que j'ai faites était de regarder la fragmentation de l'index. C'était à 33%, j'ai fait une reconstruction à une époque où rien n'utiliserait la table (sauf que, comme test, j'ai exécuté une requête sur la table en même temps que la reconstruction de l'index peut-être).

La reconstruction a pris environ 10 à 20 minutes. Pour une raison quelconque, je n'ai pas vérifié la fragmentation immédiatement après. Je l'ai vérifié le lendemain (les requêtes sont toujours lentes) et ont vu qu'il avait augmenté à 56,06%!

Screenshot of fragmentation information

Si j'essaie une autre reconstruction, je le ferai même pire? Devrais-je essayer une réorganisation à la place? (J'ai lu que Microsoft recommande une réorganisation si la fragmentation est inférieure à 30% et une reconstruction si plus de 30%)

Clause de non-responsabilité : Je suis conscient qu'il peut y avoir des mauvaises pratiques en cours ici (taille de table, conception ou quoi que ce soit) je n'ai pas créé cela, je n'ai simplement pas hérité de la responsabilité.

Edit: J'ai risqué une autre reconstruction. Ce temps vérifié immédiatement. C'était 0,01 fragmenté. J'ai de nouveau vérifié dix minutes plus tard et il était environ 1% fragmenté. J'ai vérifié à nouveau environ une minute d'intervalles et que cela devient progressivement plus fragmenté. Quelques heures plus tard, il est maintenant de 53,55% fragmenté.

Sortie de @@version:

Microsoft SQL Server 2005 - 9h00.3042.00 (x64)
10 févr. 2007 00:59:02
[.____] Copyright (c) 1988-2005 Microsoft Corporation
Edition standard (64 bits) sur Windows NT 6.0 (Build 6001: Service Pack 1)

AutoshRink is ON (Affiche "True" dans la boîte de dialogue Propriétés de la base de données)


Modifier: quelques informations supplémentaires pour donner des détails supplémentaires à la question ....

À une heure fixe chaque jour, la table obtient une mise à jour en vrac d'environ 50 000 à 100 000 rangées de nouvelles données. Pour le reste de la journée, il n'y a pas de mises à jour ni de nouveaux enregistrements, il est purement interrogé pour les données.

La clé principale est sur "enregistrement" et c'est un champ d'incrément automatique. La valeur est plus élevée pour les nouveaux inserts que toute autre chose dans le tableau, il n'ya donc pas de sandwich les données entre les données existantes dans l'index.

Voici le code de création d'index pour l'index en question ...

USE [EWS]
GO

/****** Object:  Index [IX_AmtoteAccountActivity]    Script Date: 03/03/2016 21:07:14 ******/
CREATE CLUSTERED INDEX [IX_AmtoteAccountActivity] ON [dbo].[AmtoteAccountActivity] 
(
    [AccountNumber] ASC,
    [_Date] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, 
ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

Au cas où il importe/est pertinent (je ne suis pas sûr si c'est le cas) Voici le code de création d'index pour la clé primaire ...

USE [EWS]
GO

/****** Object:  Index [PK_AmtoteAccountActivity]  Script Date: 03/03/2016 21:10:11 ******/
ALTER TABLE [dbo].[AmtoteAccountActivity] ADD  CONSTRAINT [PK_AmtoteAccountActivity] 
PRIMARY KEY NONCLUSTERED 
(
    [RecordID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]
GO

Enfin, comme suggéré par @shanky et @kookiemonster, je crois que la fragmentation (qui se développe régulièrement après la reconstruction) est causée par Auto_ShRink étant activée pour cette base de données.

2
MrVimes

Tout comme @Kookiemonster remarqua, vous avez automatiquement allumé. Et l'un des inconvénients de commandes rétractables est de nouveau fragmenter vos index:

http://www.sqlskills.com/blogs/pull/why-YOU-SHould-not-shrink-your-Data-files/

2
Marcin S.

La pulpe de page est de 98,23%. Cela signifie qu'il n'y a que 140-ISH octet gratuit par page. Ceci est plus grand que la taille minimale de la ligne. Donc, tout insert au milieu de la plage de clés et probablement toute mise à jour également, provoquera une fission et une fragmentation de page.

Vous auriez besoin d'affecter environ un million de lignes pour obtenir une fragmentation de 30% car il y a environ trois millions de pages dans l'indice. Avez-vous des processus qui écrivent à cette ampleur?

0
Michael Green

Si l'enregistrement est votre PK et que vous ne fragmentez pas, vous devez faire une flop et faire enregistrer l'index en cluster.

Avec IX_AMTOTEACECTICITATICITATICITOR COMME UN INDED non cluster, donnez-lui un facteur de remplissage de moins de 100%. Cela accélérera également des inserts. Puisqu'il s'agit d'une grosse table ne bière pas folle, même 90% ralentiront la fragmentation. Et juste planifier une reconstruction de cet indice tous les soirs.

0
paparazzo

Vous devez définir Fillactor = 90 ou moins, lors de la reconstruction de vos index. Par défaut, c'est 0 qui signifie 100%.

Transaction (insertion, mise à jour et suppression) sur une tablette à 100% de FILLFFICEDOR Cause à la page Split, qui provoque enfin une fragmentation d'index.

Il y a plusieurs raisons qui vous mènent à la fragmentation. Je peux tout vous détailler, alors passez à travers le lien donné que cela est décrit ici.

https://www.msqltips.com/sqlservertip/2261/sql-server-fragmentation-storage-basics-and-Access-Methods-Part-1-fro-9/

Merci

0
Rajesh Ranjan