DBCC SHOWCONTIG scanning 'MyTable' table...
Table: 'MyTable' (2048062382); index ID: 1, database ID: 28
TABLE level scan performed.
- Pages Scanned................................: 1019182
- Extents Scanned..............................: 127400
- Extent Switches..............................: 127399
- Avg. Pages per Extent........................: 8.0
- Scan Density [Best Count:Actual Count].......: 100.00% [127398:127400]
- Logical Scan Fragmentation ..................: 0.01%
- Extent Scan Fragmentation ...................: 77.25%
- Avg. Bytes Free per Page.....................: 135.7
- Avg. Page Density (full).....................: 98.32%
J'ai lu que la densité de balayage = 100% est très bonne et la fragmentation logique de balayage <1% est également géniale. 77% d'étendue La fragmentation de l'analyse me trouble, mais Internet dit de l'ignorer.
J'analyse une requête à effectuer une seule table. Il fonctionne ~ 30 secondes sur la première exécution, puis 200 ms sur les exécutions secondaires et suivantes. Je peux réinitialiser ce comportement avec DBCC DROPCLEANBUFFERS
.
La fragmentation de balayage de grande mesure est-elle une indice important?
(Sinon, je vais probablement ajouter une autre question sur ma requête unique).
Dans mon expérience, même si vous faites des analyses de table complets, il est peu probable que la fragmentation de l'ampleur affecte beaucoup les performances et que des modèles de requête plus typiques, il devrait être au mieux négligeable. C'est-à-dire pour les requêtes qui utilisent des données en cache qui s'inscrivent dans la mémoire - évidemment la fragmentation de tout type devient plutôt discutable si les données sont en mémoire et ne sont pas lus directement hors disque.
Maintenant, vous avez une table> 8 Go, il est donc possible que la fragmentation de l'étendue puisse être nocive pour vos questions. Si cette requête utilise une analyse de table sur 34 millions de lignes, le pire que vous obtenez (sur la première exécution seulement!) Est de 30 secondes, il est donc extrêmement improbable que l'abaissement de cette ampleur le nombre de fragmentation aille beaucoup. Ces 30 secondes sont consacrées à charger les données en mémoire et je ne peux pas comprendre que l'amélioration de la fragmentation de l'étendue vous achètera beaucoup là-bas. Si vous avez la mémoire de réserve pour conserver cette table en mémoire, vous devez peut-être envisager un travail de démarrage ou un processus d'arrière-plan qui exécute périodiquement la requête sans forcer un utilisateur à attendre, en veillant à ce qu'il reste frais dans le cache.
Hekaton pourrait être pour vous.
ConstantesCan-> Néestéloop-> Indexeek-> Néeshop-> Plan de Keylookup
Ce plan n'a pas accédé à l'ensemble de la table puisqu'il ne renvoya que 7 000 lignes sur des rangées de 34,5 m.
La quantité totale de données provenant du disque est Minuscule par rapport à la taille de la table entière.1; Temps de recherche aléatoire pour remplir les opérations de recherche clé semble dominer. La résolution des problèmes de fragmentation s'applique uniquement lorsque Scan Les opérations sont impliquées. Une fois que le motif d'accès est aléatoire comme il semble être ici, les métriques de fragmentation et de fragmentation - sont hors de propos.
Vous devriez pouvoir vérifier ce qui se passe en regardant l'activité de disque dans le moniteur de performances ou sur le moniteur de ressources tandis que la requête est en cours d'exécution - je pense que vous verrez un débit de disque très bas.
En supposant que mon analyse est correcte, voici quelques suggestions (qui peuvent être combinées) pour améliorer le temps d'exécution de la requête, en particulier avec une cache froide:
Placez le ou les fichiers de données sur un sous-système de stockage capable de mieux gérer les lectures aléatoires. Comme une estimation approximative, 30 ans/7 000 lignes sont ~ 4 ms la moyenne de la moyenne, ce qui n'est pas mauvais, cela pourrait donc être une proposition coûteuse.
Modifiez l'index non clustered pour couvrir la requête à l'aide de INCLUDE
colonnes, éliminant ainsi le besoin de recherches clés et donc la majeure partie de l'activité de disque aléatoire. Ceci est probablement la meilleure solution, même si vous sacrifiez un peu d'espace de stockage supplémentaire pour cela. Espérons que la table n'est pas super large.
1 En supposant que des tailles approximativement égales de rangée.
Aussi, comme un de côté, DBCC SHOWCONTIG
a été obsolète depuis un certain temps - le remplacement de l'avenir est sys.dm_db_index_physical_stats
.