Leistungsunterschied zwischen Innodb und Myisam in Mysql

8

Ich habe eine MySQL-Tabelle mit über 30 Millionen Datensätzen, die ursprünglich mit myisam gespeichert wurde. Hier ist eine Beschreibung der Tabelle:

Ich würde die folgende Abfrage für diese Tabelle ausführen, die normalerweise etwa 30 Sekunden benötigt. Ich würde @eid jedes Mal ändern, um Datenbank- oder Platten-Caching zu vermeiden.

%Vor%

Ich habe diese Tabelle dann in innoDB konvertiert, ohne irgendwelche weiteren Änderungen vorzunehmen, und die gleiche Abfrage kehrt jetzt jedes Mal, wenn ich die Abfrage durchführe, weniger als eine Sekunde zurück. Selbst wenn ich zufällig @eid einstelle, um Zwischenspeichern zu vermeiden, kehrt die Abfrage in weniger als einer Sekunde zurück.

Ich habe die Unterschiede zwischen den beiden Speicherarten untersucht, um zu versuchen, die dramatische Verbesserung der Leistung zu erklären, aber ich konnte mir nichts einfallen lassen. Tatsächlich deutet vieles von dem, was ich lese, dass Myisam schneller sein sollte.

Die Abfragen, die ich durchführe, sind gegen eine lokale Datenbank, wobei keine anderen Prozesse zum Zeitpunkt der Tests auf die Datenbank treffen.

    
opike 30.03.2012, 17:27
quelle

3 Antworten

15

Das ist ein überraschend großer Leistungsunterschied, aber ich kann mir ein paar Dinge vorstellen, die dazu beitragen könnten.

MyISAM wurde in der Vergangenheit als schneller angesehen als InnoDB, aber für neuere Versionen von InnoDB gilt das für viel kleinere Anwendungsfälle. MyISAM ist in der Regel schneller für Tabellen-Scans von schreibgeschützten Tabellen. In den meisten anderen Anwendungsfällen finde ich InnoDB normalerweise schneller. Oft um ein Vielfaches schneller. Tabellensperren sind ein Todesstoß für MyISAM in den meisten meiner MySQL-Nutzung.

MyISAM speichert Indizes in seinem Schlüsselpuffer. Vielleicht haben Sie den Schlüsselpuffer zu klein eingestellt, um den Index für Ihre etwas größere Tabelle effektiv zwischenzuspeichern.

MyISAM hängt vom Betriebssystem ab, um Tabellendaten aus den .MYD-Dateien im Betriebssystemdatenträgercache zwischenzuspeichern. Wenn das Betriebssystem nicht mehr genügend Arbeitsspeicher zur Verfügung hat, beginnt es seinen Plattencache zu entladen. Das könnte es zwingen, weiter von der Festplatte zu lesen.

InnoDB speichert beide Indizes und Daten in einem eigenen Speicherpuffer. Sie können das Betriebssystem anweisen, seinen Festplattencache nicht zu verwenden, wenn Sie innodb_flush_method auf O_DIRECT setzen, obwohl dies unter OS X nicht unterstützt wird.

InnoDB puffert normalerweise Daten und Indizes in 16kb-Seiten. Je nachdem, wie Sie den Wert von @eid zwischen Abfragen ändern, hat er möglicherweise bereits die Daten für eine Abfrage zwischengespeichert, da die Datenträger von einer vorherigen Abfrage gelesen wurden.

Stellen Sie sicher, dass Sie die Indizes identisch erstellt haben. Verwenden Sie explain, um zu überprüfen, ob MySQL den Index verwendet. Da Sie die Ausgabe von describe anstelle von show create table oder show indexes von enthalten, kann ich nicht sagen, ob entity_id Teil eines zusammengesetzten Indexes ist. Wenn es nicht der erste Teil eines zusammengesetzten Indexes wäre, würde es nicht verwendet.

Wenn Sie eine relativ moderne Version von MySQL verwenden, führen Sie den folgenden Befehl aus, bevor Sie die Abfrage ausführen:

Profilerstellung = 1;

Dadurch wird die Abfrageprofilerstellung für Ihre Sitzung aktiviert. Führen Sie nach dem Ausführen der Abfrage

aus

zeige Profile;

Dies zeigt Ihnen die Liste der Abfragen, für die Profile verfügbar sind. Ich denke, dass es standardmäßig die letzten 20 hält. Angenommen, Ihre Abfrage war die erste, führen Sie:

Zeige Profil für Abfrage 1;

Sie sehen dann die Dauer jeder Phase Ihrer Abfrage. Dies ist äußerst nützlich, um zu bestimmen, was (z. B. Tabellensperren, Sortieren, Erstellen von temporären Tabellen usw.) eine langsame Abfrage verursacht.

    
Robert Stewart 30.03.2012, 18:03
quelle
6
___ qstnhdr ___ Leistungsunterschied zwischen Innodb und Myisam in Mysql ___ answer9948201 ___

Das ist ein überraschend großer Leistungsunterschied, aber ich kann mir ein paar Dinge vorstellen, die dazu beitragen könnten.

MyISAM wurde in der Vergangenheit als schneller angesehen als InnoDB, aber für neuere Versionen von InnoDB gilt das für viel kleinere Anwendungsfälle. MyISAM ist in der Regel schneller für Tabellen-Scans von schreibgeschützten Tabellen. In den meisten anderen Anwendungsfällen finde ich InnoDB normalerweise schneller. Oft um ein Vielfaches schneller. Tabellensperren sind ein Todesstoß für MyISAM in den meisten meiner MySQL-Nutzung.

MyISAM speichert Indizes in seinem Schlüsselpuffer. Vielleicht haben Sie den Schlüsselpuffer zu klein eingestellt, um den Index für Ihre etwas größere Tabelle effektiv zwischenzuspeichern.

MyISAM hängt vom Betriebssystem ab, um Tabellendaten aus den .MYD-Dateien im Betriebssystemdatenträgercache zwischenzuspeichern. Wenn das Betriebssystem nicht mehr genügend Arbeitsspeicher zur Verfügung hat, beginnt es seinen Plattencache zu entladen. Das könnte es zwingen, weiter von der Festplatte zu lesen.

InnoDB speichert beide Indizes und Daten in einem eigenen Speicherpuffer. Sie können das Betriebssystem anweisen, seinen Festplattencache nicht zu verwenden, wenn Sie innodb_flush_method auf O_DIRECT setzen, obwohl dies unter OS X nicht unterstützt wird.

InnoDB puffert normalerweise Daten und Indizes in 16kb-Seiten. Je nachdem, wie Sie den Wert von @eid zwischen Abfragen ändern, hat er möglicherweise bereits die Daten für eine Abfrage zwischengespeichert, da die Datenträger von einer vorherigen Abfrage gelesen wurden.

Stellen Sie sicher, dass Sie die Indizes identisch erstellt haben. Verwenden Sie explain, um zu überprüfen, ob MySQL den Index verwendet. Da Sie die Ausgabe von describe anstelle von show create table oder show indexes von enthalten, kann ich nicht sagen, ob entity_id Teil eines zusammengesetzten Indexes ist. Wenn es nicht der erste Teil eines zusammengesetzten Indexes wäre, würde es nicht verwendet.

Wenn Sie eine relativ moderne Version von MySQL verwenden, führen Sie den folgenden Befehl aus, bevor Sie die Abfrage ausführen:

Profilerstellung = 1;

Dadurch wird die Abfrageprofilerstellung für Ihre Sitzung aktiviert. Führen Sie nach dem Ausführen der Abfrage

aus

zeige Profile;

Dies zeigt Ihnen die Liste der Abfragen, für die Profile verfügbar sind. Ich denke, dass es standardmäßig die letzten 20 hält. Angenommen, Ihre Abfrage war die erste, führen Sie:

Zeige Profil für Abfrage 1;

Sie sehen dann die Dauer jeder Phase Ihrer Abfrage. Dies ist äußerst nützlich, um zu bestimmen, was (z. B. Tabellensperren, Sortieren, Erstellen von temporären Tabellen usw.) eine langsame Abfrage verursacht.

    
___ tag123mysql ___ MySQL ist ein freies, relationales Datenbank-Managementsystem (RDBMS), das die strukturierte Abfragesprache (SQL) verwendet. Verwenden Sie dieses Tag NICHT für andere DBs wie SQL Server, SQLite usw. Dies sind verschiedene DBs, die alle SQL verwenden, um die Daten zu verwalten. ___ tag123database ___ Eine Datenbank ist eine organisierte Sammlung von Daten. Es ist die Sammlung von Schemas, Tabellen, Abfragen, Berichten, Ansichten und anderen Objekten. Die Daten sind typischerweise so organisiert, dass sie Aspekte der Realität so modellieren, dass sie Prozesse unterstützen, die Informationen benötigen. Verwenden Sie dieses Tag, wenn Sie Fragen zum Entwerfen einer Datenbank haben. Wenn es sich um ein bestimmtes Datenbankverwaltungssystem (z. B. MySQL) handelt, verwenden Sie stattdessen dieses Tag. ___ tag123innodb ___ InnoDB ist eine ACID-kompatible Transaktionsspeicher-Engine für MySQL, die MultiVersion Concurrency Control (MVCC) verwendet. ___ tag123myisam ___ MyISAM ist eine nicht-transaktionale Speicher-Engine für MySQL. Es bietet schnelles Speichern und Abrufen sowie Volltextsuchfunktionen. Außerdem ist es der Standardspeicher-Engine-Typ für Versionen vor 5.5. ___ qstntxt ___

Ich habe eine MySQL-Tabelle mit über 30 Millionen Datensätzen, die ursprünglich mit myisam gespeichert wurde. Hier ist eine Beschreibung der Tabelle:

Ich würde die folgende Abfrage für diese Tabelle ausführen, die normalerweise etwa 30 Sekunden benötigt. Ich würde @eid jedes Mal ändern, um Datenbank- oder Platten-Caching zu vermeiden.

%Vor%

Ich habe diese Tabelle dann in innoDB konvertiert, ohne irgendwelche weiteren Änderungen vorzunehmen, und die gleiche Abfrage kehrt jetzt jedes Mal, wenn ich die Abfrage durchführe, weniger als eine Sekunde zurück. Selbst wenn ich zufällig @eid einstelle, um Zwischenspeichern zu vermeiden, kehrt die Abfrage in weniger als einer Sekunde zurück.

Ich habe die Unterschiede zwischen den beiden Speicherarten untersucht, um zu versuchen, die dramatische Verbesserung der Leistung zu erklären, aber ich konnte mir nichts einfallen lassen. Tatsächlich deutet vieles von dem, was ich lese, dass Myisam schneller sein sollte.

Die Abfragen, die ich durchführe, sind gegen eine lokale Datenbank, wobei keine anderen Prozesse zum Zeitpunkt der Tests auf die Datenbank treffen.

    
___ answer14929533 ___

Was sind Ihre Indexdefinitionen? Es gibt Möglichkeiten, wie Sie Indizes für MyISAM erstellen können, in denen Ihre Indexfelder nicht verwendet werden, wenn Sie denken, sie würden dies tun.

    
___
Eric Petroelje 30.03.2012 17:40
quelle
1

Was sind Ihre Indexdefinitionen? Es gibt Möglichkeiten, wie Sie Indizes für MyISAM erstellen können, in denen Ihre Indexfelder nicht verwendet werden, wenn Sie denken, sie würden dies tun.

    
Christopher Brand 18.02.2013 04:33
quelle

Tags und Links