Best of MyISAM und InnoDB

17

Ist es möglich, InnoDB zu veranlassen, die gleichen Indizes wie MyISAM anstelle von Clustered-Indizes zu verwenden, da der Arbeitsspeicher begrenzt ist und gleichzeitig die Leistung der Parallelität genutzt wird?

Rick James
quelle

Antworten:

14

Der gen_clust_index (Clustered Index) unter der Haube von InnoDB enthält Einträge von Primärschlüsseln sowie Zeilen-IDs. Das Interessante an der Verwendung des gen_clust_index ist die Tatsache, dass nicht eindeutige Indizes, die Sie erstellen, immer eine entsprechende Zeilen-ID für den gen_clust_index einer Tabelle haben. Es gibt also immer Doppelindex-Lookups, einen für den Sekundärindex und einen für den gen_clust_index.

Alle Versuche, das Layout einer Tabelle oder eines Primärschlüssels zu verbessern, werden aufgrund von gen_clust_index oder bestenfalls geringfügigen Ergebnissen aufgehoben.

BEISPIEL

Einige Leute versuchen, einen MyISAM in der PRIMARY KEY-Reihenfolge zu sortieren. Gemäß Abschnitt 7 von MySQL Database Design and Tuning unter der Überschrift "Speichern einer Tabelle in Indexreihenfolge":

Wenn Sie häufig große Bereiche indizierter Daten aus einer Tabelle abrufen oder die Ergebnisse konsistent nach demselben Indexschlüssel sortieren, können Sie myisamchk mit der Option --sort-records ausführen. Wenn Sie dies tun, weisen Sie MySQL an, die Daten der Tabelle in derselben physischen Reihenfolge wie der Index zu sortieren. Alternativ können Sie die ALTER TABLE-Anweisung mit einer ORDER BY-Option für eine bestimmte Spalte kombinieren, um dieselben Ergebnisse zu erzielen.

Zugegeben, das funktioniert und funktioniert effektiv für MyISAM . Sie könnten ALTER TABLE ... ORDER BY col1, col2, ..., coln gegen InnoDB ausführen, wobei die Spalten die des PRIMARY KEY sein können oder nicht. Dies führt für InnoDB nicht zu schnelleren Ergebnissen, da ... das stimmt ... Sie jedes Mal den gen_clust_index konsultieren müssen.

Einige Benutzer ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;können das Zeilenformat der Tabelle mit FIXED festlegen und die Leseleistung ohne weitere Änderungen um 20% steigern. Dies funktioniert und funktioniert effektiv für MyISAM . Dies führt für InnoDB nicht zu schnelleren Ergebnissen, da ... das stimmt ... Sie jedes Mal den gen_clust_index konsultieren müssen.

Sie können Folgendes für eine InnoDB-Tabelle mit dem Namen mydb.mytb ausführen:

CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;

Dadurch wird die Tabelle in der Reihenfolge der Zeilen im gen_clust_index abgelegt. Dies kann bestenfalls marginale Ergebnisse für InnoDB liefern, weil ... das stimmt ... Sie jedes Mal den gen_clust_index konsultieren müssen.

Jetzt lass uns ein bisschen lächerlich werden. Es gibt eine NoSQL-Schnittstelle zum Abfragen (nur SELECT) von MyISAM und InnoDB, die als HandlerSocket-Schnittstelle (früher als HANLDER bezeichnet) bezeichnet wird . Auf diese Weise haben Sie Zugriff auf Daten, mit denen Sie alle SQL-, ACID- und MVCC-Anweisungen umgehen können Protokolle . Obwohl es möglich ist, ist es IMHO AUCH MÖGLICH, CODE UND WARTUNG ZU KOMPLIZIEREN. AFAIK gibt es nichts im Druck, das besagt, ob die HandlerSocket-Schnittstelle mit dem gen_clust_index interagiert oder nicht.

Zusammenfassend gibt es viele Möglichkeiten, eine Katze zu häuten. In diesem Fall können Sie die Katze (den gen_clust_index) nicht erreichen. Ich denke, aus diesem Grund besteht MyISAM weiterhin für seine Leseleistung, seine Flexibilität bei der Tabellenreihenfolge, das Format der Tabellenzeilen und die Tools, die es unterstützen. InnoDB wird so lange auf seine ACID-Konformität ausgelegt bleiben, bis eine mutige Seele den InnoDB-Quellcode aufgreift und ihn in etwas verwandelt, das das Beste von MyISAM und InnoDB bietet .

RolandoMySQLDBA
quelle
3

Der Clustered-Index ist möglicherweise der Grund für die Parallelität von InnoDB auf herkömmlichen Spin-Laufwerken.

Der Zugriff auf eine Zeile über den Clustered-Index erfolgt schnell, da sich die Zeilendaten auf derselben Seite befinden, auf der die Indexsuche führt. Wenn eine Tabelle groß ist, spart die Clustered-Index-Architektur häufig eine Platten-E / A-Operation im Vergleich zu Speicherorganisationen, die Zeilendaten auf einer anderen Seite als dem Indexdatensatz speichern. (MyISAM verwendet beispielsweise eine Datei für Datenzeilen und eine andere für Indexdatensätze.)

Festplatten-E / A ist teuer. Das zu reduzieren ist ein großer Vorteil, um die Parallelität zu verbessern.

Wenn die Datenträger-E / A billiger werden und ein geringerer Engpass entsteht (z. B. wenn die SSD-Technologie stabiler wird), kann Oracle entscheiden, die Funktionsweise von InnoDB-Indizes zu ändern. Es ist wahrscheinlicher, dass es gleich bleibt, da dieselbe Technologie die Begrenzung des Arbeitsspeichers weniger problematisch macht.

Derek Downey
quelle
3

Kurze Antwort: Nein.

InnoDB-Cluster werden über den Primärschlüssel erstellt. Wenn kein Primärschlüssel vorhanden ist, wird der erste eindeutige Index ausgewählt. Wenn kein eindeutiger Index vorhanden ist, wird ein versteckter 6-Byte-Schlüssel für das Clustering erstellt.

Wenn Sie den verborgenen 6-Byte-Schlüssel haben, beziehen sich sekundäre Indizes auf diesen Schlüssel und nicht auf exakte Zeiger auf Zeilenpositionen (wie in MyISAM), sodass Sie einen sekundären Schlüssel durchlaufen und dann einen primären Schlüssel durchlaufen, um Ihre Datensätze zu finden .


Um ein wenig von Ihrer Frage zu extrapolieren, gehe ich davon aus, dass Sie sich Sorgen über die Anpassung des Gedächtnisses an einen Baum machen, da sich zur effizienten Suche alle Wurzelknoten im Gedächtnis befinden sollten, da Sie diesen Pfad immer gehen müssen, um Ihre Blattseiten zu finden?

Dies ist wahr, aber ein Trost ist, dass kommerzielle Datenbanken versuchen, ihre Bäume so fett wie möglich zu machen, anstatt tief. Versuchen Sie, xtrabackup --stats auf Ihren Daten auszuführen, um zu sehen. Beispielsweise:

<INDEX STATISTICS>
  table: test/table1, index: PRIMARY, space id: 12, root page 3
  estimated statistics in dictionary:
    key vals: 25265338, leaf pages 497839, size pages 498304
  real statistics:
     level 2 pages: pages=1, data=5395 bytes, data/pages=32%
     level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
        leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%

Es gab 497839 Blattseiten (~ 8 GB), aber nur 416 Seiten darüber (6,5 MB). Ich habe diesen Befehl einige Male für Produktionsdaten ausgeführt, und es überrascht mich immer, wenn ich Millionen von Datensätzen und nur Seiten der Stufe 1-3 + Blattseiten habe.

Morgan Tocker
quelle