Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Leistung:MyISAM vs. InnoDB

Ein wichtiger Faktor für die Datenbankleistung ist die von der Datenbank verwendete Speicher-Engine und insbesondere ihre Tabellen. Unterschiedliche Speicher-Engines bieten in einer Situation eine bessere Leistung als in einer anderen. Für den allgemeinen Gebrauch gibt es zwei Konkurrenten, die in Betracht gezogen werden müssen. Dies sind MyISAM, die standardmäßige MySQL-Speicher-Engine, oder InnoDB, eine in MySQL integrierte alternative Engine, die für Hochleistungsdatenbanken vorgesehen ist. Bevor wir den Unterschied zwischen den beiden Speicher-Engines verstehen können, müssen wir den Begriff „Sperren“ verstehen.

Was ist Sperren in MySQL?

Um die Integrität der in Datenbanken gespeicherten Daten zu schützen, verwendet MySQL Sperren. Sperren bedeutet einfach ausgedrückt, Daten vor dem Zugriff zu schützen. Wenn eine Sperre angewendet wird, können die Daten nur durch die Abfrage geändert werden, die die Sperre initiiert hat. Das Sperren ist eine notwendige Komponente, um die Genauigkeit der gespeicherten Informationen sicherzustellen. Für jede Speicher-Engine wird eine andere Sperrmethode verwendet. Abhängig von Ihren Daten und Abfragepraktiken kann eine Engine eine andere übertreffen. In dieser Serie werden wir uns die beiden häufigsten Arten von Sperren ansehen, die von unseren beiden Speicher-Engines verwendet werden.

Tabellensperre: Die Technik zum Sperren einer gesamten Tabelle, wenn eine oder mehrere Zellen in der Tabelle aktualisiert oder gelöscht werden müssen. Das Sperren von Tabellen ist die Standardmethode, die von der Standardspeicher-Engine MyISAM verwendet wird.

Beispiel:MyISAM-Tabellensperre Spalte A Spalte B Spalte C
Aktualisierung von Abfrage 1 Reihe 1 Schreiben Daten Daten
Abfrage 2 AUSWÄHLEN (Warten) Zeile 2 Daten Daten Daten
Abfrage 3 UPDATE (Warten) Reihe 3 Daten Daten Daten
Abfrage 4 AUSWÄHLEN (Warten) Reihe 4 Daten Daten Daten
Abfrage 5 AUSWÄHLEN (Warten) Reihe 5 Daten Daten Daten
Das Beispiel zeigt, wie ein einzelner Schreibvorgang die gesamte Tabelle sperrt, wodurch andere Abfragen auf das Ende der UPDATE-Abfrage warten müssen.

Sperren auf Zeilenebene: Der Vorgang des Sperrens eines effektiven Bereichs von Zeilen in einer Tabelle, während eine oder mehrere Zellen innerhalb des Bereichs geändert oder gelöscht werden. Das Sperren auf Zeilenebene wird von der InnoDB-Speicher-Engine verwendet und ist für Hochleistungsdatenbanken vorgesehen.

Beispiel:InnoDB-Sperre auf Zeilenebene Spalte A Spalte A Spalte A
Aktualisierung von Abfrage 1 Reihe 1 Schreiben Daten Daten
Abfrage 2 AUSWÄHLEN Zeile 2 Lesen Daten Daten
Aktualisierung von Abfrage 3 Reihe 3 Daten Schreiben Daten
Abfrage 4 AUSWÄHLEN Reihe 4 Lesen Lesen Lesen
Abfrage 5 AUSWÄHLEN Reihe 5 Lesen Daten Lesen
Das Beispiel zeigt, wie die Verwendung von Sperren auf Zeilenebene die Ausführung mehrerer Abfragen für einzelne Zeilen ermöglicht, indem nur die zu aktualisierenden Zeilen und nicht die gesamte Tabelle gesperrt werden.

MyISAM vs. InnoDB

Durch den Vergleich der beiden Speicher-Engines kommen wir zum Kern des Arguments zwischen der Verwendung von InnoDB gegenüber MyISAM. Eine Anwendung oder Website mit einer häufig verwendeten Tabelle funktioniert mit der InnoDB-Speicher-Engine hervorragend, da Engpässe beim Sperren von Tabellen behoben werden. Die Frage der Verwendung eines über dem anderen ist jedoch subjektiv, da keines von beiden in allen Situationen perfekt ist. Beide Speicher-Engines haben Stärken und Einschränkungen. Genaue Kenntnisse der Datenbankstruktur und der Abfragepraktiken sind entscheidend für die Auswahl der besten Speicher-Engine für Ihre Tabellen.

MyISAM übertrifft InnoDB bei großen Tabellen, die wesentlich mehr Lese- als Schreibaktivitäten erfordern. Die Lesbarkeit von MyISAM stellt InnoDB in den Schatten, da das Sperren der gesamten Tabelle schneller ist, als herauszufinden, welche Zeilen in der Tabelle gesperrt sind. Je mehr Informationen in der Tabelle enthalten sind, desto mehr Zeit benötigt InnoDB, um herauszufinden, auf welche nicht zugegriffen werden kann. Wenn Ihre Anwendung auf riesige Tabellen angewiesen ist, die Daten nicht häufig ändern, wird MyISAM InnoDB übertreffen. Umgekehrt übertrifft InnoDB MyISAM, wenn sich Daten innerhalb der Tabelle häufig ändern. Tabellenänderungen schreiben mehr Daten als lesen Daten pro Sekunde. In diesen Situationen kann InnoDB mit großen Mengen von Anfragen einfacher Schritt halten, als die gesamte Tabelle für jede einzelne zu sperren.

Sollte ich InnoDB mit WordPress-, Magento- oder Joomla-Sites verwenden?

Die kurze Antwort hier ist ja, in den meisten Fällen. Die hilfreichsten Mitarbeiter von Liquid Web in Hosting-Supportteams sind auf mehrere Engpässe durch Tabellensperren gestoßen, wenn Kunden einige Standard-Webanwendungen von heute verwenden. Die meisten Benutzer beliebter Anwendungen von Drittanbietern wie WordPress, Magento und Joomla haben nur begrenzte Kenntnisse über die zugrunde liegenden Datenbankkomponenten oder den beteiligten Code, um eine fundierte Entscheidung über Speicher-Engines zu treffen. Die meisten Tabellensperrungsengpässe dieser Content-Management-Systeme (CMS) werden im Allgemeinen behoben, indem alle Tabellen für die Website auf InnoDB anstatt auf das standardmäßige MyISAM umgestellt werden. Wenn Sie viele dieser Arten von CMS auf Ihrem Server hosten, wäre es vorteilhaft, die Standardspeicher-Engine in MySQL so zu ändern, dass InnoDB für alle neuen Tabellen verwendet wird, sodass alle neuen Tabelleninstallationen mit InnoDB beginnen.

Festlegen der Standard-Speicher-Engine

Legen Sie Ihre Standardspeicher-Engine auf InnoDB fest, indem Sie default_storage_engine=InnoDB hinzufügen zu [mysqld] Abschnitt der Systemkonfigurationsdatei unter: /etc/my.cnf. Der Neustart des MySQL-Dienstes ist erforderlich, damit der Server Änderungen an der Datei erkennt.

~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M

Konvertieren aller Tabellen zwischen MyISAM und InnoDB

Leider verfügt MySQL nicht von Natur aus über eine Option zum Konvertieren von Tabellen, so dass jede Tabelle einzeln geändert werden muss. Das Support-Team von Liquid Web hat einen leicht verständlichen Wartungsplan für diesen Prozess zusammengestellt. Das Skript, das Sie auf dem erforderlichen Server per Shell-Zugriff (SSH) ausführen können, konvertiert alle Tabellen zwischen Speicher-Engines.

HinweisPlanen Sie entsprechend, wenn Sie Batch-Vorgänge dieser Art durchführen, nur für den Fall, dass es zu Ausfallzeiten kommt. Es empfiehlt sich, alle Ihre MySQL-Datenbanken zu sichern, bevor Sie eine Änderung dieser Größenordnung implementieren. Dies bietet einen einfachen Wiederherstellungspunkt, um Datenverluste zu vermeiden.

Schritt 1:  Vorbereitung

Planen Sie, zu einer Tageszeit zu beginnen, zu der Ausfallzeiten nur minimale Folgen haben würden. Dieser Prozess selbst erfordert keine Ausfallzeit, jedoch kann eine Ausfallzeit erforderlich sein, um sich von unvorhergesehenen Umständen zu erholen.

Schritt 2:  Alle Datenbanken in einer Datei sichern

Der folgende Befehl erstellt eine einzelne Dateisicherung aller Datenbanken mit dem Namen all-databases-backup.sqld und kann gelöscht werden, sobald die Konvertierung erfolgreich war und keine offensichtlichen Probleme vorliegen.
mysqldump --all-databases > all-databases-backup.sql

Schritt 3:  Vorhandene Tabellen-Engines in einer Datei aufzeichnen

Führen Sie das folgende Skript aus, um die vorhandenen Tabellen-Engines in einer Datei mit dem Namen table-engine-backup.sql aufzuzeichnen . Sie können diese Datei dann später "importieren" oder "ausführen", um sie bei Bedarf wieder in ihre ursprünglichen Engines zu konvertieren.

mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql

Wenn Sie die Tabellen-Engines aus irgendeinem Grund zurücksetzen müssen, führen Sie Folgendes aus:
mysql < table-engine-backup.sql

Schritt 4a:  MyISAM-Tabellen in InnoDB konvertieren

Der folgende Befehl wird auch dann fortgesetzt, wenn eine Tabelle fehlschlägt, und informiert Sie darüber, welche Tabellen nicht konvertiert werden konnten. Die Ausgabe wird in der Datei namens convert-to-innodb.log gespeichert zur späteren Überprüfungw.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log

Schritt 4b:Konvertieren Sie alle InnoDB-Tabellen in MyISAM

Dieser Befehl wird auch dann fortgesetzt, wenn eine Tabelle fehlschlägt, und informiert Sie darüber, welche Tabellen nicht konvertiert werden konnten. Die Ausgabe wird auch in der Datei namens convert-to-myisam.log gespeichert zur späteren Überprüfung.

mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log

Konvertieren einer einzelnen Tabelle zwischen MyISAM und InnoDB

Die folgenden Befehle veranschaulichen, wie das Konvertieren einer einzelnen Tabelle durchgeführt wird.

HinweisErsetzen Sie Datenbankname durch den richtigen Datenbanknamen und Tabellenname durch den richtigen Tabellennamen. Stellen Sie sicher, dass Sie über eine gültige Sicherung der betreffenden Tabelle verfügen, bevor Sie fortfahren.

Eine einzelne Tabelle in einer Datei sichern
mysqldump database_name table_name > backup-table_name.sql

Eine einzelne Tabelle in InnoDB konvertieren

mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’

Eine einzelne Tabelle in MyISAM konvertieren:

mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’

Lesen Sie unsere anderen Artikel in dieser Reihe, MySQL-Leistung:Identifizieren langer Abfragen, um langsame Abfragen in Ihrer Datenbank zu lokalisieren. Bleiben Sie dran für unseren nächsten Artikel, in dem wir uns mit Caching und Optimierung befassen.

Seriennavigation<>