Erstellen Sie einen sehr großen Primärschlüsselindex neu


13

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=onOption 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.


4
@Techy REORGANIZEreduziert selbst bei hoher Fragmentierung die Fragmentierung von Blattseiten und den kompakten Speicherplatz REBUILD, nur weniger effizient. Sind Sie sicher, dass die Größe auf Fragmentierung zurückzuführen ist? Was ist der Füllfaktor?
Dan Guzman

Wissen Sie, was die Fragmentierung verursacht? Wie bald nach Ihrem Umbau sind Sie wieder auf Platz 1? Können Sie weitere Informationen zu Ihrem Tisch veröffentlichen?
Pacreely

2
@Techy Ich habe die Frage bearbeitet, um basierend auf Ihren Kommentaren einige zusätzliche Informationen hinzuzufügen. Es wäre hilfreich, wenn Sie auch die Tabellendefinition in die Frage aufnehmen und zusätzliche Details zu "Die Tabelle wird gesperrt, auch wenn sie online neu erstellt wird". Welche Art von Wartezeiten sehen Sie?
Zwei

Antworten:


9

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 ... REORGANIZEErklärung abgeben, die von Dan Guzman in den Kommentaren angegeben wurde. Dadurch wird kein Index so rationalisiert wie bei einer REBUILDOperation, 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.


4

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 FULLSCANDies 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:

  1. 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 die avg_fragmentation_in_percentSpalte.

  2. 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 die avg_page_space_used_in_percentSpalte. Diese Spalte wird nur bei Verwendung von SAMPLEDoder DETAILEDmode 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. Der REORGANIZEVorgang ist online und verschiebt die Seiten nacheinander, um sie wieder in physische Reihenfolge zu bringen. Wenn Sie eine REORGANIZEAnweisung 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 einer REORGANIZEgroß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. REORGANIZEEin stark fragmentierter Index kann auch länger dauern als ein REBUILD.

Sie werden häufig Ratschläge erhalten, eine REBUILDfür stark fragmentierte Indizes durchzuführen , anstatt eine REORGANIZE- 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 werden ALTER INDEX...REBUILD. Wenn Sie den Index mit ONLINE=ONausführen, sollten Sie in der Lage sein, das Blockieren zu minimieren. Das muss jedoch REBUILDnoch 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 der WAIT_AT_LOW_PRIORITYOption 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 LaufzeitREBUILDOperation 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.


Fragmentierung mit niedriger Dichte (auch als "interne Fragmentierung" bezeichnet) wird häufig durch a behoben 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.
Granger

2

Beachten

Nach diesem Kommentar:

Sie verlieren Zeilen, die während des Kopierens eingefügt werden. Wenn Sie dies verhindern möchten, indem Sie die Tabelle sperren, haben Sie das gleiche Problem wie das in seiner Frage angegebene OP. Auch 200Gb werden nicht kostenlos kommen :-) - Marco 5. September 17 um 11:18

... 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:

  • Skripting LiveTablein eine leereNewTable
  • Kopieren der LiveTablein dieNewTable
  • Umbenennen LiveTableinOldTable
  • Umbenennen NewTableinLiveTable

Verwenden Sie natürlich stattdessen den Namen Ihrer Tabelle LiveTable.


Oreo, ich würde den gleichen Ansatz wie Sie verwenden. Auch wenn während des Kopiervorgangs Zeilen eingefügt werden, können Sie diese nach dem Umbenennen der NewTable in LiveTable hinzufügen. Das Hauptproblem, das Sie hier vermeiden, ist die verlängerte Ausfallzeit. Sie könnten es sogar bcp (I / O-Kopie in). Es ist keine so schlechte Idee, also verstehe ich die Ablehnung auch nicht :-)
Koen D

1

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:

(WAIT_AT_LOW_PRIORITY (MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = SELF))

0

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:

Insert from OldTable into LiveTable
  Where not exists (select From OldTable Where LiveTable.Key = OldTable.Key)

Wenn der Schlüssel eine Identitätsspalte ist, müssen Sie einen etwas anderen Ansatz verwenden.


Wie unter Oreos Antwort erwähnt, funktioniert seine Methode nicht, wenn der Originaltabelle noch Daten hinzugefügt werden, es sei denn, Sie sperren die Originaltabelle, die den Zweck der Übung
Tom V - zunichte macht. Versuchen Sie topanswers.xyz

-2

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.