Ist eine Fragmentierung mit hohem Ausmaß ein Problem?

7
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%

Ich habe gelesen, dass die Scan-Dichte = 100% sehr gut ist und die logische Scan-Verwaltung <1% ebenfalls großartig ist. 77% Extent Scan Fragmentation stört mich, aber das Internet sagt, es zu ignorieren.

Ich analysiere eine langsame Abfrage mit einer Tabelle. Es läuft ~ 30 Sekunden bei der ersten Ausführung, dann 200 ms bei der zweiten und nachfolgenden Ausführung. Ich kann dieses Verhalten mit zurücksetzen DBCC DROPCLEANBUFFERS.

Ist die High-Extent-Scan-Fragmentierung ein wichtiger Hinweis?

(Wenn nicht, werde ich wahrscheinlich eine weitere Frage zu meiner Einzeltabellenabfrage hinzufügen.)

Amy B.
quelle
Welche Version von SQL Server verwenden Sie? Wie hoch ist die Zeilenanzahl der Tabelle, in der Sie die Fragmentierungsstufe überprüfen?
Kin Shah
Die Extent-Fragmentierung wird als "externe" Fragmentierung bezeichnet und tritt auf, wenn die Extents in einem Index nicht zusammenhängend sind. Beeinflusst Readahead, jedoch nicht so stark. Abhängig von der Anzahl der Zeilen und der Anzahl der Seiten kann dies die Leistung beeinträchtigen. Wenn die Tabelle weniger als 1000 Seiten hat, hilft es nicht viel, selbst wenn Sie den Index neu erstellen
Kin Shah
@Kin ...depending on the row count and number of pages...und Arten von Abfragen, die ausgeführt werden ... Selbst wenn Sie vollständige Tabellenscans durchführen, ist es unwahrscheinlich, dass dies die Leistung stark beeinträchtigt, aber für typischere Abfragemuster sollte dies bestenfalls vernachlässigbar sein. Zumindest nach meiner Erfahrung.
Aaron Bertrand
1
Wenn Sie von "Es läuft ~ 30 Sekunden bei der ersten Ausführung, dann 200 ms bei der zweiten" ausgehen, würde ich sagen, dass die 2. Ausführung schnell ist, da die Daten zwischengespeichert werden. Wenn Sie sich jetzt besser auf die Behebung dieser Abfrage konzentrieren möchten, müssen Sie uns das Tabellenschema (einschließlich der Indizes), die Abfrage selbst und den Ausführungsplan der Abfrage (den tatsächlichen, nicht den geschätzten) anzeigen. Sie können auch den Plan-Explorer von SQL Sentry verwenden , um den tatsächlichen Plan zu generieren und hier hochzuladen.
Marian
@ Kin SqlServer2012. 34.530.707 Zeilen, 8.153.456 KB Daten.
Amy B

Antworten:

9

Nach meiner Erfahrung ist es selbst bei vollständigen Tabellenscans unwahrscheinlich, dass die Fragmentierung die Leistung stark beeinträchtigt, und für typischere Abfragemuster sollte sie bestenfalls vernachlässigbar sein. Dies gilt für Abfragen, bei denen zwischengespeicherte Daten verwendet werden, die in den Speicher passen. Offensichtlich wird eine Fragmentierung jeglicher Art eher problematisch, wenn sich die Daten im Speicher befinden und nicht direkt von der Festplatte gelesen werden.

Jetzt haben Sie eine Tabelle mit> 8 GB, sodass es möglich ist, dass die Fragmentierung Ihrer Abfragen schädlich ist. Wenn diese Abfrage einen Tabellenscan über 34 Millionen Zeilen verwendet und das Schlimmste (nur bei der ersten Ausführung!) 30 Sekunden beträgt, ist es äußerst unwahrscheinlich, dass eine Verringerung der Fragmentierungszahl in diesem Ausmaß viel hilft. Diese 30 Sekunden werden damit verbracht, die Daten in den Speicher zu laden, und ich kann mir nicht vorstellen, dass eine Verbesserung des Ausmaßes der Fragmentierung Ihnen dort viel bringt. Wenn Sie über genügend Speicher verfügen, um diese Tabelle im Speicher zu halten, sollten Sie möglicherweise einen Startjob oder einen Hintergrundprozess in Betracht ziehen, der die Abfrage regelmäßig ausführt, ohne dass ein Benutzer darauf warten muss, um sicherzustellen, dass sie im Cache aktuell bleibt.

Hekaton könnte für Sie sein.

Aaron Bertrand
quelle
Oh, oh, Sie möchten vielleicht betonen, dass dies bei sehr großen Tischen (in meinem Fall 50 GB +) ein Problem sein kann . Selbst wenn sich Daten im Speicher befinden, kann eine schlechte Seitendichte (auch bei geringer Fragmentierung) zu Problemen und Abfragen mit geringer Leistung sowie Beschwerden von Benutzern führen.
Janis Veinbergs
@Janis Mein erster erster Absatz sagt "unwahrscheinlich" nicht "unmöglich" und habe ich Ihren genauen Punkt am Anfang meines zweiten Absatzes nicht angesprochen? Was noch wichtiger ist: Wie haben Sie festgestellt, dass eine schlechte Seitendichte die genaue und einzige Ursache für Ihre Benutzerbeschwerden ist?
Aaron Bertrand
Keine Sorge, ich wollte nur mehr Wert auf dieses Wort legen :) Nun, ich kann nicht sagen, dass es die einzige Ursache ist. Nur dass es Fälle gibt, in denen die logische Fragmentierung gering und akzeptabel ist, die Seitendichte jedoch verbessert werden könnte und Benutzer sich beschweren. Wenn dieser Clustered-Index neu erstellt wird, kehrt alles zum Normalzustand zurück. Vielleicht verursacht etwas anderes dies, das durch Wiederaufbau behoben wird ...
Janis Veinbergs
Ok, ich denke, es ist nicht das logische Fragmentierungsproblem, das ich hatte, sondern wahrscheinlich ein Nebeneffekt beim Wiederherstellen: Statistiken werden aktualisiert, der Plan-Cache für diese Tabellen wird ungültig und mit effektiveren Plänen neu generiert.
Janis Veinbergs
@ JanisVeinbergs, also haben Sie einen Umbau durchgeführt, keinen Umbau? Ja, das ist anders. Bei einer Neuorganisation werden die Statistiken zunächst einmal nicht aktualisiert. Und wahrscheinlich hätte das Aktualisieren von Statistiken allein ohne Neuerstellung oder Neuorganisation zu denselben Verbesserungen geführt.
Aaron Bertrand
4

ConstantScan-> NestedLoop-> IndexSeek-> NestedLoop-> KeyLookup-Plan

Dieser Plan hat nicht auf die gesamte Tabelle zugegriffen, da nur 7.000 von 34,5 Millionen Zeilen zurückgegeben wurden.

Die Gesamtmenge der von der Festplatte kommenden Daten ist im Vergleich zur Größe der gesamten Tabelle 1 winzig. Die zufällige Suchzeit zur Erfüllung der wichtigsten Suchvorgänge scheint zu dominieren. Das Beheben von Fragmentierungsproblemen tritt nur auf, wenn Scanvorgänge beteiligt sind. Sobald das Zugriffsmuster zufällig ist, wie es hier zu sein scheint, sind Fragmentierung - und Fragmentierungsmetriken - irrelevant.

Sie sollten in der Lage sein, die Vorgänge zu überprüfen, indem Sie die Festplattenaktivität in Performance Monitor oder Resource Monitor beobachten, während die Abfrage ausgeführt wird. Ich gehe davon aus, dass der Festplattendurchsatz sehr niedrig ist.

Unter der Annahme, dass meine Analyse korrekt ist, finden Sie hier einige Vorschläge (die kombiniert werden können), um die Ausführungszeit der Abfrage zu verbessern, insbesondere bei einem kalten Cache:

  • Legen Sie die Datendatei (en) auf ein Speichersubsystem, das zufällige Lesevorgänge besser verarbeiten kann. Als grobe Schätzung entspricht 30s / 7.000 Zeilen einer durchschnittlichen Suchzeit von ~ 4ms, was nicht schlecht ist. Dies könnte also eine teure Angelegenheit sein.

  • Ändern Sie den nicht gruppierten Index so, dass die Abfrage mithilfe von INCLUDESpalten abgedeckt wird , sodass keine Schlüsselsuche und damit der größte Teil der zufälligen Festplattenaktivität erforderlich ist. Dies ist wahrscheinlich die beste Lösung, selbst wenn Sie etwas zusätzlichen Speicherplatz dafür opfern. Hoffentlich ist der Tisch nicht super breit.

1 Angenommen, ungefähr gleiche Zeilengrößen.


Abgesehen davon DBCC SHOWCONTIGist es auch schon eine ganze Weile veraltet - der Ersatz für die Zukunft ist sys.dm_db_index_physical_stats.

Jon Seigel
quelle