Database
 sql >> Datenbank >  >> RDS >> Database

Kürzen des Transaktionsprotokollfetts

Bei vielen SQL Server-Workloads, insbesondere OLTP, kann das Transaktionsprotokoll der Datenbank ein Engpass sein, der die Zeit verlängert, die zum Abschluss einer Transaktion benötigt wird. Die meisten Leute nehmen an, dass das E/A-Subsystem der eigentliche Engpass ist, da es nicht in der Lage ist, mit der Menge an Transaktionsprotokollen Schritt zu halten, die durch die Arbeitslast generiert werden.

Schreiblatenz des Transaktionsprotokolls

Die Latenz von Schreibvorgängen in das Transaktionsprotokoll kann mit sys.dm_io_virtual_file_stats überwacht werden DMV und korreliert mit dem WRITELOG Wartezeiten, die auf dem System auftreten. Ich habe 2011 ein Demovideo zur Analyse von Transaktionsprotokoll-E/A aufgenommen, daher werde ich das alles in diesem Beitrag nicht wiederholen. Das Video erhalten Sie hier und den Democode hier (sofort produktiv einsetzbar).

Wenn die Schreiblatenz höher ist, als Sie für Ihr E/A-Subsystem erwarten würden, kann das E/A-Subsystem nicht mithalten, wie die allgemeine Annahme ist. Bedeutet das aber, dass das I/O-Subsystem verbessert werden muss? Nicht unbedingt.

Auf vielen Client-Systemen habe ich festgestellt, dass ein erheblicher Teil der generierten Protokolldatensätze unnötig ist, und wenn Sie die Anzahl der generierten Protokolldatensätze reduzieren können, reduzieren Sie die Menge an Transaktionsprotokollen, die auf die Festplatte geschrieben werden. Dies sollte zu einer Reduzierung der Schreiblatenz führen und somit die Transaktionsabschlusszeit verkürzen.

Es gibt zwei Hauptursachen für die Generierung irrelevanter Protokolldatensätze:ungenutzte Nonclustered-Indizes und fragmentierte Indizes.

Unused Nonclustered Indexes

Immer wenn ein Datensatz in eine Tabelle eingefügt wird, muss ein Datensatz in jeden nicht gruppierten Index eingefügt werden, der in der Tabelle definiert ist (mit Ausnahme von gefilterten Indizes mit entsprechenden Filtern, die ich ab diesem Punkt ignorieren werde). Dies bedeutet, dass für jede Tabelleneinfügung zusätzliche Protokollsätze generiert werden, mindestens einer pro Nonclustered-Index. Das Gleiche gilt für das Löschen eines Datensatzes in einer Tabelle – die übereinstimmenden Datensätze müssen aus allen Nonclustered-Indizes gelöscht werden. Bei einer Aktualisierung eines Tabellendatensatzes werden Nonclustered-Index-Datensätze nur aktualisiert, wenn die Schlüsselspalte(n) des Nonclustered-Index oder die eingeschlossene(n) Spalte(n) Teil der Aktualisierung waren.

Diese Operationen sind natürlich notwendig, um jeden Nonclustered-Index in Bezug auf die Tabelle korrekt zu halten, aber wenn der Nonclustered-Index von der Arbeitslast nicht verwendet wird, dann sind die Operationen und die von ihnen erzeugten Protokollaufzeichnungen unnötiger Overhead. Wenn diese ungenutzten Indizes fragmentiert werden (was ich später in diesem Beitrag besprechen werde), werden die regulären Indexwartungsaufgaben auch auf sie angewendet und noch mehr Protokolldatensätze generiert (aus dem Index REBUILD). oder REORGANIZE Operationen) völlig unnötig.

Nicht verwendete Indizes stammen aus einer Vielzahl von Quellen, z. B. wenn jemand versehentlich einen Index pro Tabellenspalte erstellt, jemand jeden Index erstellt, der von den DMVs für fehlende Indizes vorgeschlagen wird, oder jemand, der alle vom Database Tuning Advisor vorgeschlagenen Indizes erstellt. Es kann auch sein, dass sich die Workload-Eigenschaften geändert haben und daher die früher nützlichen Indizes nicht mehr verwendet werden.

Unabhängig davon, woher sie stammen, sollten nicht verwendete Indizes entfernt werden, um ihren Overhead zu reduzieren. Mit dem DMV sys.dm_db_index_usage_stats können Sie feststellen, welche Indizes nicht verwendet werden, und ich empfehle Ihnen, die Beiträge meiner Kollegen Kimberly L. Tripp (hier) und Joe Sack (hier und hier) zu lesen, da sie erklären, wie Sie das DMV richtig verwenden.

Indexfragmentierung

Die meisten Leute halten die Indexfragmentierung für ein Problem, das Abfragen betrifft, die große Datenmengen lesen müssen. Während dies eines der Probleme ist, die durch Fragmentierung verursacht werden können, ist Fragmentierung aufgrund ihrer Art und Weise auch ein Problem.

Die Fragmentierung wird durch einen Vorgang verursacht, der als Seitenaufteilung bezeichnet wird. Die einfachste Ursache für eine Seitenteilung ist, wenn ein Indexdatensatz auf einer bestimmten Seite eingefügt werden muss (aufgrund seines Schlüsselwerts) und die Seite nicht über genügend freien Speicherplatz verfügt. In diesem Szenario finden die folgenden Vorgänge statt:

  • Eine neue Indexseite wird zugewiesen und formatiert
  • Einige der Datensätze von der ganzen Seite werden auf die neue Seite verschoben, wodurch auf der erforderlichen Seite freier Platz geschaffen wird
  • Die neue Seite wird in die Indexstruktur eingebunden
  • Der neue Datensatz wird auf der gewünschten Seite eingefügt

Alle diese Operationen generieren Protokolldatensätze, und wie Sie sich vorstellen können, kann dies erheblich mehr sein, als zum Einfügen eines neuen Datensatzes auf einer Seite erforderlich ist, die keine Seitenteilung erfordert. Im Jahr 2009 habe ich eine Analyse der Seitenaufteilungskosten in Bezug auf das Transaktionsprotokoll gebloggt und einige Fälle gefunden, in denen eine Seitenaufteilung über 40-mal mehr Transaktionsprotokoll generierte als eine normale Beilage!

Der erste Schritt zur Reduzierung der zusätzlichen Kosten besteht darin, ungenutzte Indizes zu entfernen, wie ich oben beschrieben habe, damit sie keine Seitenteilungen erzeugen. Der zweite Schritt besteht darin, mithilfe von sys.dm_db_index_physical_stats verbleibende Indizes zu identifizieren, die fragmentiert werden (und daher unter Seitenaufteilungen leiden müssen). DMV (oder der neue SQL Sentry Fragmentation Manager) und proaktives Erstellen von freiem Speicherplatz in ihnen mithilfe eines Index-Füllfaktors. Ein Füllfaktor weist SQL Server an, leeren Platz auf Indexseiten zu lassen, wenn der Index erstellt, neu erstellt oder reorganisiert wird, damit Platz zum Einfügen neuer Datensätze vorhanden ist, ohne dass eine Seitenaufteilung erforderlich ist, wodurch die zusätzlich generierten Protokolldatensätze reduziert werden.

Natürlich gibt es nichts umsonst – der Kompromiss bei der Verwendung von Füllfaktoren besteht darin, dass Sie proaktiv zusätzlichen Speicherplatz in den Indizes bereitstellen, um zu verhindern, dass mehr Protokolldatensätze generiert werden – aber das ist normalerweise ein guter Kompromiss. Die Auswahl eines Füllfaktors ist relativ einfach und ich habe hier darüber gebloggt.

Zusammenfassung

Das Reduzieren der Schreiblatenz einer Transaktionsprotokolldatei bedeutet nicht immer, dass Sie zu einem schnelleren E/A-Subsystem wechseln oder die Datei in einen eigenen Teil des E/A-Subsystems trennen. Mit einer einfachen Analyse der Indizes in Ihrer Datenbank können Sie möglicherweise die Menge der generierten Transaktionsprotokolldatensätze erheblich reduzieren, was zu einer entsprechenden Verringerung der Schreiblatenz führt.

Es gibt andere, subtilere Probleme, die sich auf die Leistung des Transaktionsprotokolls auswirken können, und ich werde diese in einem zukünftigen Beitrag untersuchen.