it-swarm.com.de

MySQL indiziert die Wartung

Ich habe viel darüber recherchiert, wie Indizes in MySQL verwaltet werden können, um eine Fragmentierung zu verhindern und die Ausführung einiger Abfragen irgendwie zu optimieren.

Ich kenne diese Formel, die das Verhältnis zwischen dem für eine Tabelle maximal verfügbaren Speicherplatz und dem von Daten und Indizes verwendeten Speicherplatz berechnet.

Meine Hauptfragen sind jedoch immer noch unbeantwortet. Vielleicht liegt dies an der Tatsache, dass ich mit der Indexpflege in SQL Server vertraut bin, und ich neige dazu zu denken, dass es in MySQL irgendwie ähnlich sein sollte.

In SQL Server können mehrere Indizes vorhanden sein, von denen jeder unterschiedliche Fragmentierungsstufen aufweisen kann. Dann können Sie eine auswählen und eine 'REORGANIZE'- oder' REBUILD'-Operation in diesem bestimmten Index ausführen, ohne den Rest zu beeinflussen.

Nach meinem besten Wissen gibt es keine "Tabellenfragmentierung" als solche, und SQL Server bietet kein Tool zum Beheben der "Tabellenfragmentierung". Es werden Tools zum Überprüfen der Indexfragmentierung (verstanden als Verhältnis zwischen der Anzahl der von einem Index verwendeten Seiten und der Fülle dieser Seite und der Kontiguität) sowie der internen und externen Fragmentierung bereitgestellt.

All das ist ziemlich einfach zu verstehen, zumindest für mich.

Wenn es darum geht, Indizes in MySQL zu verwalten, gibt es nur das oben erwähnte Konzept der Tabellenfragmentierung.

Eine Tabelle in MySQL kann mehrere Indizes haben, aber wenn ich das Fragmentierungsverhältnis mit dieser berühmten Formel überprüfe, sehe ich nicht die Fragmentierung jedes Index, sondern die Tabelle als Ganzes.

Wenn ich die Indizes in MySQL optimieren möchte, wähle ich keinen bestimmten Index für die Bearbeitung aus (wie in SQL Server). Stattdessen führe ich eine 'OPTIMIZE'-Operation in der gesamten Tabelle aus, die vermutlich alle Indizes betrifft.

Wenn die Tabelle in MySQL optimiert wird, wird das Verhältnis zwischen dem von Daten + Indizes verwendeten Speicherplatz und dem Gesamtspeicherplatz reduziert, was auf eine physische Neuorganisation der Festplatte hindeutet, was sich in einer Reduzierung des physischen Speicherplatzes niederschlägt. Bei der Indexfragmentierung geht es jedoch nicht nur um den physischen Speicherplatz, sondern auch um die Struktur des Baums, die im Laufe der Zeit aufgrund von Einfügungen und Aktualisierungen geändert wurde.

Endlich habe ich eine Tabelle in InnoDB/MySQL bekommen. Diese Tabelle enthält 3 Millionen Datensätze, 105 Spalten und 55 Indizes. Es sind 1,5 GB ohne Indizes (2,1 GB).

Diese Tabelle wird tausende Male am Tag zum Aktualisieren und Einfügen aufgerufen (wir löschen keine Datensätze).

Diese Tabelle wurde jahrelang erstellt und ich weiß mit Sicherheit, dass niemand Indizes verwaltet.

Ich hatte erwartet, dort eine große Fragmentierung zu finden, aber wenn ich die Fragmentierungsberechnung wie vorgeschrieben durchführe

free_space / (data_length + index_length)

es stellt sich heraus, dass ich nur eine Fragmentierung von 0,2% habe. IMHO ist das ziemlich unrealistisch.

Die großen Fragen sind also :

  1. Wie überprüfe ich die Fragmentierung eines bestimmten Index in MySQL, nicht der gesamten Tabelle?
  2. Behebt OPTIMIZE TABLE tatsächlich die interne/externe Fragmentierung eines Index wie in SQL Server?
  3. Wenn ich eine Tabelle in MySQL optimiere, werden dann tatsächlich alle Indizes in der Tabelle neu erstellt?
  4. Ist es realistisch zu glauben, dass die Reduzierung des physischen Speicherplatzes eines Index (ohne den Baum selbst neu zu erstellen) tatsächlich zu einer besseren Leistung führt?
12
Nicolas

Die Indexfragmentierung wird stark überbewertet. Mache dir darüber keine Sorgen.

Zwei benachbarte, etwas leere Blöcke werden von InnoDB als natürliche Verarbeitung zusammengeführt.

Durch zufällige Aktionen auf einem BTree wird es auf natürliche Weise zu durchschnittlich 69% voll. Sicher, das ist nicht 100%, aber der Aufwand für das "Reparieren" lohnt sich nicht.

SHOW TABLE STATUS Gibt Ihnen einige Metriken an, die jedoch fehlerhaft sind. "Data_free" enthält bestimmten "freien" Speicherplatz, jedoch keinen anderen "freien" Speicherplatz.

In jedem Block ist nicht genutzter Speicherplatz vorhanden. freie 16KB Blöcke; freie "Extents" (nMB-Chunks); MVCC-Zeilen, die darauf warten, geerntet zu werden; Nicht-Blattknoten haben ihre eigene Fragmentierung; usw.

Percona und Oracle haben unterschiedliche Sichtweisen auf die Größe (Anzahl der Blöcke) eines Index. Ich finde keinen von ihnen wegen der begrenzten Definition von "frei" nützlich. Es scheint, dass Blöcke (jeweils 16 KB) in Blöcken (mehrere MB) zugewiesen werden, was zu der Annahme führt, dass alle Arten von Fragmentierung vorliegen. In Wirklichkeit ist es normalerweise nur der größte Teil eines dieser Multi-MB-Blöcke. Und OPTIMIZE TABLE Erfüllt nicht unbedingt den gesamten Speicherplatz.

Wenn SQL Server BTrees verwendet, liegt es an der Aussage, dass "keine Fragmentierung" vorliegt. Überlegen Sie, was bei einem "Block Split" passiert. Oder denken Sie an den Aufwand einer kontinuierlichen Defragmentierung. So oder so verlierst du.

Beachten Sie außerdem, dass eine Tabelle und ein Index im Wesentlichen identische Strukturen sind:

  • B + Tree, basierend auf einem Index
  • Die "Daten" basieren auf dem PRIMARY KEY; Jeder Sekundärindex ist ein B + -Baum, der auf seinem Index basiert.
  • Der Blattknoten der "Daten" enthält alle Spalten der Tabelle.
  • Der Blattknoten eines Sekundärindex enthält die Spalten dieses Sekundärindex sowie die Spalten des PRIMARY KEY.

Wenn Sie innodb_file_per_table = ON Haben, können Sie die Schrumpfung (falls vorhanden) nach OPTIMIZE TABLE deutlich sehen, indem Sie die Größe der Datei .ibd Betrachten. Für OFF sind die Informationen in ibdata1 Vergraben, aber SHOW TABLE STATUS Ist möglicherweise ziemlich genau, da der gesamte "freie" Speicherplatz zu jeder Tabelle gehört. Nun, bis auf die vorab zugewiesenen Brocken.

Möglicherweise stellen Sie fest, dass eine frisch optimierte Datei pro Tabelle genau 4M, 5M, 6M oder 7M Data_free enthält. Dies ist wiederum die Vorabzuweisung und das Versäumnis, Ihnen die winzigen Details zu geben.

Ich arbeite seit über einem Jahrzehnt mit InnoDB zusammen. Ich habe mit Tausenden von großen und kleinen Tischen gearbeitet. Ich sage, dass nur eine von tausend Tabellen wirklich OPTIMIZE TABLE Benötigt. Die Verwendung auf anderen Tischen ist eine Verschwendung.

105 Spalten sind viel, aber vielleicht nicht zu viele.

Haben Sie 55 Indizes für die Tabelle one? Das ist schlecht. Das sind 55 Updates pro INSERT. Lassen Sie uns das weiter diskutieren. Denken Sie daran, dass INDEX(a) nutzlos ist, wenn Sie auch INDEX(a,b) haben. Und INDEX(flag) ist wegen der geringen Kardinalität nutzlos. (Aber INDEX(flag, foo) kann nützlich sein.)

Q1: Es gibt keine gute Möglichkeit, die Daten oder die Sekundärindizes auf alle Formen der Fragmentierung zu überprüfen.

Q2, Q3: OPTIMIZE TABLE Erstellt die Tabelle neu, indem CREATEing eine neue Tabelle und INSERTing alle Zeilen, dann RENAMEing und DROPping. Das erneute Einfügen der Daten in PK-Reihenfolge stellt sicher, dass Daten gut defragmentiert ist. Die Indizes sind eine andere Sache.

F4: Sie könntenDROP und reCREATE jeden Index, um ihn zu bereinigen. Dies ist jedoch ein äußerst langsamer Prozess. 5.6 hat einige Beschleunigungen, aber ich weiß nicht, ob sie bei der Defragmentierung helfen.

Es ist auch möglich, ALTER TABLE ... DISABLE KEYS Und dann ENABLE sie. Dies kann zu einer effizienteren Neuerstellung aller Sekundärindizes auf einmal.

6
Rick James

Wie überprüfe ich die Fragmentierung eines bestimmten Index in MySQL, nicht der gesamten Tabelle?

Bestehen.

Behebt OPTIMIZE TABLE tatsächlich die interne/externe Fragmentierung eines Index wie in SQL Server?

Die Tabelle und ihre Indizes werden vollständig neu erstellt.

Wenn ich eine Tabelle in MySQL optimiere, werden dann tatsächlich alle Indizes in der Tabelle neu erstellt?

Das ist die gleiche Frage mit der gleichen Antwort.

Ist es realistisch zu glauben, dass die Reduzierung des physischen Speicherplatzes eines Index (ohne den Baum selbst neu zu erstellen) tatsächlich zu einer besseren Leistung führt?

Es ist nicht realistisch zu glauben, dass Sie den Platz reduzieren könnten ohne den Baum neu aufzubauen. Sie gehen zusammen.

1
user207421