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.)
...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.Antworten:
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.
quelle
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
INCLUDE
Spalten 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 SHOWCONTIG
ist es auch schon eine ganze Weile veraltet - der Ersatz für die Zukunft istsys.dm_db_index_physical_stats
.quelle