Ich habe eine SQL-Datenbank, die auf Azure gehostet wird. Das Problem ist, dass die Größe außer Kontrolle gerät. Ich kann eine Fragmentierung von bis zu 99% in den Cluster-Indizes des Primärschlüssels feststellen.
Ich kann alle anderen Indizes mit online=on
Option neu erstellen und die Leistung wird dadurch nicht beeinträchtigt. Die Größe eines der PK-Clustered-Indizes ist größer als 200 GB, und in diesem Fall führt a zu einer REBUILD...WITH (ONLINE=ON)
Sperrung.
Wir haben Benutzer aus allen Zeitzonen, die auf die Site zugreifen. Daher kann ich keine Zeit finden, in der ich den Index offline neu erstellen kann.
Was ist die beste Strategie, um große Indizes ohne Ausfallzeiten auf der Site neu zu erstellen?
Ich glaube, eine Reorganisation wird nicht helfen, da die Fragmentierung 99% beträgt. Das Problem ist, dass die Tabelle auch online gesperrt wird. Das Hauptproblem ist, dass der Index größer als 200 GB ist. Der Primärschlüssel ist eine Ganzzahl.
REORGANIZE
reduziert selbst bei hoher Fragmentierung die Fragmentierung von Blattseiten und den kompakten SpeicherplatzREBUILD
, nur weniger effizient. Sind Sie sicher, dass die Größe auf Fragmentierung zurückzuführen ist? Was ist der Füllfaktor?Antworten:
Auch wenn es etwas spät ist, werde ich eine Antwort mit der Hoffnung einreichen, dass dies hilft oder zumindest einige zusätzliche Ideen / Kommentare zu diesem Thema verschmäht, da ich denke, dass dies eine gute Frage ist.
Erstens, und ich weiß nicht, ob Sie dies tun oder nicht, aber gehen Sie bitte nicht davon aus, dass hohe Fragmentierungsstufen im Index immer zu einer schlechten Leistung führen. Veraltete Statistiken (z. B. sys.dm_db_stats_properties ) und hohe Leerzeichen pro Seite ( dh Spalte avg_page_space_used_in_percent in sys.dm_db_index_physical_stats dmv ) sind in Bezug auf Leistungsprobleme relevanter als Fragmentierung allein. Ja, stark fragmentierte Indizes führen zu mehr Vorauslesungen, und in der Regel werden veraltete Statistiken und höhere Leerzeichen pro Seite in Verbindung mit Fragmentierung angezeigt. Die Fragmentierung ist jedoch nicht direkt an die Optimierung des Abfrageplans oder an die Speicherkapazität des Index von der Festplatte gebunden wird tatsächlich verbrauchen. Abfragepläne werden von Statistiken beeinflusst und Ihr Speicherbedarf wird mit mehr Leerraum aufgebläht . Zum Beispiel ein Index, der zu 99% fragmentiert ist, aber einen Durchschnitt von weniger als 5% aufweist. Leerzeichen und aktuelle Statistiken verursachen wahrscheinlich keine drastischen Leistungsprobleme im Vergleich zu einem schlechten Ausführungsplan aufgrund veralteter Statistiken oder einem ständigen Paging eines Index, der zu groß ist, um vollständig in den Speicher zu passen, da eine erhebliche Menge vorhanden ist pro Seite vorhandener Leerraum.
Wenn Fragmentierung wirklich ein Problem ist , können Sie es ONLINE reduzieren, indem Sie eine
ALTER INDEX ... REORGANIZE
Erklärung abgeben, die von Dan Guzman in den Kommentaren angegeben wurde. Dadurch wird kein Index so rationalisiert wie bei einerREBUILD
Operation, aber die Fragmentierung wird verringert. Der Schlüssel hier besteht darin, Fenster mit geringerer Nutzung in Ihrer Datenbank zu identifizieren und diese dann auszuführen. Dies kann 15 Minuten oder mehrere Stunden dauern. Je länger, desto besser. Der Schlüssel hier ist jedoch, dass dieser Vorgang nicht rückgängig gemacht wird und alle erzielten Fortschritte beibehalten werden, selbst wenn Sie ihn während der Ausführung beenden.Wenn es in einer perfekten Welt, in der Ihre Fragmentierung beseitigt wurde, sinnvoller wäre, die Partitionierung für diese Tabelle zu verwenden? Die Azure SQL-Datenbank ermöglicht die Tabellenpartitionierung, und Microsoft hat einen großartigen Artikel veröffentlicht, in dem einige Partitionierungsstrategien für die Azure SQL-Datenbank beschrieben werden . Wenn Ihre Daten nicht flüchtig sind, kann eine Partitionierung dazu beitragen, den Wartungsaufwand zu verringern. In Verbindung mit der Tabellenkomprimierung können Sie möglicherweise sogar Ihren gesamten Speicherbedarf reduzieren. Die frühere Antwort von Alberto Murillo spielt auf die Verwendung der horizontalen Partitionierung an basierend auf einer Datenregion, und dieser Ansatz kann dazu beitragen, einige Wartungsfenster für Sie zu erstellen, da Ihre Daten regional spezifischer als global wären.
Der Übergang zu einer partitionierten Tabelle ist nicht einfach, da derzeit keine Wartungsfenster vorhanden sind. Möglicherweise können Sie jedoch einen von Maria Zakourdaev beschriebenen Ansatz verwenden, bei dem partitionierte Ansichten über der aktuellen Tabelle und eine neue partitionierte Tabelle zum Starten der Partitionierung verwendet werden zukünftige Daten. Im Laufe der Zeit (und hoffentlich werden Ihre alten Daten gelöscht) können Sie schließlich vollständig auf die partitionierte Tabelle übergehen. Auch hier kenne ich Ihre Daten oder Ihre Anwendung nicht, aber vielleicht können Sie diesen Ansatz anwenden.
quelle
Zunächst ist es wichtig zu prüfen, ob Fragmentierung wichtig ist.
Wenn Ihre Abfrage nur einzeilige Suchvorgänge ausführt, bemerken Sie möglicherweise überhaupt keine Fragmentierung. In modernen SANs können durch das Caching auf SAN-Ebene phyiskale E / A-Vorgänge schnell genug ausgeführt werden, sodass die Fragmentierung keine Rolle spielt. Auf einer SSD kann das zufällige E / A-Muster, das durch das Scannen eines fragmentierten Index verursacht wird, tatsächlich zu einer besseren Leistung führen als nicht fragmentierte Daten.
Oft bemerken die Leute, dass die Neuerstellung eines Index ein Leistungsproblem behoben hat. Durch die Neuerstellung eines Index werden auch neue Statistiken erstellt. Es kann sein, dass der eigentliche Fix frische Statistiken sind und nicht den Index neu erstellen.
UPDATE STATISTICS...WITH FULLSCAN
Dies kann eine billigere, schnellere und weniger aufdringliche Methode sein, um dasselbe Leistungsproblem zu lösen.Wenn Sie keine durch Fragmentierung verursachten Probleme haben, müssen Sie möglicherweise viel Zeit und Mühe aufwenden, um keinen tatsächlichen Gewinn zu erzielen.
Zweitens gibt es zwei Arten der Fragmentierung:
Physikalische Fragmentierung. Daran denken die meisten Menschen, wenn sie an Fragmentierung denken. Die Seiten sind nicht in Ordnung und müssen neu bestellt werden. Beim Scannen eines Index kann diese Art der Fragmentierung manchmal ein Problem sein. Ich habe allgemein festgestellt, dass dies den größten Einfluss auf die Leistung bei physischen Lesevorgängen hat. Wenn Sie sich die Ergebnisse von ansehen
sys.dm_db_index_physical_stats
, ist diese Nummer dieavg_fragmentation_in_percent
Spalte.Fragmentierung mit geringer Dichte. Diese Fragmentierung wird durch Seiten verursacht, die nur teilweise mit Daten gefüllt sind. Sie haben eine geringe Datendichte , da Ihre Daten auf mehr Seiten als erforderlich verteilt sind. Infolgedessen erfordert das Lesen der Daten mehr E / A, da die Daten auf mehr Seiten als erforderlich verteilt sind. Dies kann sich sowohl auf logische als auch auf physische Lesevorgänge auswirken. Wenn Sie sich die Ergebnisse von ansehen
sys.dm_db_index_physical_stats
, ist diese Nummer dieavg_page_space_used_in_percent
Spalte. Diese Spalte wird nur bei Verwendung vonSAMPLED
oderDETAILED
mode ausgefüllt.Was tun Sie dagegen?
Physische Fragmentierung : Wenn Sie einfach nur hohe Zahlen suchen
avg_fragmentation_in_percent
, sollten Sie wirklich überlegen, ob Sie Ihre Zeit verschwenden. Stellen Sie sicher, dass Sie eine tatsächliche Abfrage haben, die schlecht funktioniert, und verwenden Sie eine Testumgebung, um zu bestätigen, dass Sie ein Problem beheben, indem Sie die Fragmentierung beseitigen.Sie können die physische Fragmentierung beheben, indem Sie dies tun
ALTER INDEX...REORGANIZE
. DerREORGANIZE
Vorgang ist online und verschiebt die Seiten nacheinander, um sie wieder in physische Reihenfolge zu bringen. Wenn Sie eineREORGANIZE
Anweisung auf halbem Weg beenden, wird jede bereits ausgeführte Arbeit beibehalten. Es wird nur die eine Seite verschoben, die gerade verschoben wird. Das Ausführen einerREORGANIZE
großen Tabelle mit starker Fragmentierung kann mehr Speicherplatz für das gesamte Transaktionsprotokoll erfordern und im vollständigen Wiederherstellungsmodus möglicherweise eine erhebliche Anzahl von Transaktionsprotokollsicherungen generieren.REORGANIZE
Ein stark fragmentierter Index kann auch länger dauern als einREBUILD
.Sie werden häufig Ratschläge erhalten, eine
REBUILD
für stark fragmentierte Indizes durchzuführen , anstatt eineREORGANIZE
- Dies liegt daran, dass die Neuerstellung von Grund auf effizienter sein kann. Eine Reorganisation kann jedoch eine "onlineere" Operation sein und wird manchmal sogar für stark fragmentierte Indizes bevorzugt.Fragmentierung mit niedriger Dichte kann nicht durch behoben werden
REORGANIZE
. Es kann nur durch eine behoben werdenALTER INDEX...REBUILD
. Wenn Sie den Index mitONLINE=ON
ausführen, sollten Sie in der Lage sein, das Blockieren zu minimieren. Das muss jedochREBUILD
noch für einen Moment gesperrt werden, um den alten Index gegen den neuen Index auszutauschen. In einem sehr ausgelasteten System kann das Erreichen dieser exklusiven Sperre manchmal ein Problem sein. Sie sollten in der Lage sein, zu bestätigen, ob Sie dieses Problem haben, indem Sie sp_whoisactive verwenden , um die Blockierung während Ihrer Neuerstellung zu untersuchen und die Details der Sperren und Wartezeiten zu überprüfen. Die Verwendung derWAIT_AT_LOW_PRIORITY
Option kann nützlich sein, wenn Sie wissen, dass eine geringe Auslastung bevorsteht und sich Ihre Neuerstellung für diesen Tausch "einschleichen" kann, wenn die Aktivität niedrig genug ist, um diese Sperre zu erreichen. Beachten Sie, dass eine lange LaufzeitREBUILD
Operation wird auch eine lange offene Transaktion sein. Offene Transaktionen mit langer Laufzeit können ihre eigenen Probleme haben, die mit der Verwendung / Wiederverwendung von Transaktionsprotokollen zusammenhängen. Wenn Sie Spiegelungs- oder Verfügbarkeitsgruppen verwenden, gibt es auch Überlegungen zum Wiederherstellen des Transaktionsprotokolls auf dem sekundären Replikat.quelle
REORGANIZE
. Aus der BOL : "Durch das Reorganisieren werden auch die Indexseiten komprimiert." Nun, solange der aktuelle FILLFACTOR des Index die Dichte zulässt, nach der Sie suchen.Beachten
Nach diesem Kommentar:
... Ich sehe, wie dieser Ansatz nicht funktionieren wird.
Ich werde diese Antwort als Beispiel dafür belassen, was nicht zu tun ist.
Wenn in Ihrer Azure-Datenbank mehr als 200 GB frei sind, können Sie mit der "Neuerstellung" hinterhältig werden, indem Sie Ihre Daten in eine völlig neue Tabelle kopieren und dort bestellen.
Versuchen:
LiveTable
in eine leereNewTable
LiveTable
in dieNewTable
LiveTable
inOldTable
NewTable
inLiveTable
Verwenden Sie natürlich stattdessen den Namen Ihrer Tabelle
LiveTable
.quelle
Wenn ein Index gut gestaltet ist, sollten wir im Idealfall nicht mit dem Verriegelungsmechanismus herumspielen müssen.
Für mich klingt es so, als müssten Sie die Sperre akzeptieren, um den Clustered-Index zu defragmentieren. Wenn die Wahrscheinlichkeit groß ist, dass dies erneut auftritt, sollten Sie den Clustered-Index neu gestalten (er sollte eng, eindeutig, statisch und immer größer sein).
Ich bin nicht sicher, welche Version von SQL Server Sie verwenden, aber Sie könnten 2012 Folgendes versuchen:
SET DEADLOCK_PRIORITY LOW
- Dies teilt der Engine mit, dass die Indexwiederherstellung das Deadlock-Opfer sein sollte, wenn / falls eines auftritt.MaxDOP = 1
- Der MaxDOP-Wert begrenzt die Gesamtzahl der parallel zum Erstellen des Index verwendeten logischen CPUs (ab 2005 - nur Enterprise Edition).Sie können auch die Konfiguration der Seiten- / Zeilensperren ändern, aber ich würde das nicht ohne Tests tun. Sie könnten die Sperre nur verschlimmern, insbesondere wenn es sich um einen schlecht gestalteten Index handelt.
Ab 2014 gibt es die folgende Option, mit der die Engine grundsätzlich angewiesen wird, andere Sitzungen fortzusetzen und die Online-Indexoperation zu warten:
quelle
Ich habe den gleichen Ansatz wie Oreo oben mit großem Erfolg verwendet! Das einzige, was fehlt, ist, dass Sie ein Aktualisierungsskript ausführen müssen, nachdem Sie die Daten kopiert und die letzte Umbenennung vorgenommen haben.
Das Update sieht folgendermaßen aus:
Wenn der Schlüssel eine Identitätsspalte ist, müssen Sie einen etwas anderen Ansatz verwenden.
quelle
Versuchen Sie, mithilfe von Sharding Daten Ihrer Datenbank geografisch zu verteilen. Sie können dann verschiedene Wartungsfenster für jeden geografischen Standort identifizieren, und die Zeit für die Wartung wird kürzer. Dies verbessert auch die Leistung. Sie können mehr über diesen Artikel erfahren . Warten Sie nicht, bis die Datenbank größer wird.
Wenn große Datenbanken und Benutzer rund um die Uhr verbunden sind, müssen Sie die Indexreorganisation verwenden und nur Statistiken aktualisieren, die aktualisiert werden müssen (sp_updatestats), um den Zeitaufwand für die Wartung und die Auswirkungen auf die Benutzer zu minimieren.
Hoffe das hilft.
quelle