Ich arbeite an einem Projekt, das viele Datenbankschreibvorgänge umfasst ( 70% Einfügungen und 30% Lesevorgänge ). Dieses Verhältnis würde auch Aktualisierungen einschließen, die ich als ein Lese- und ein Schreibvorgang betrachte. Die Lesevorgänge können verschmutzt sein (z. B. benötige ich zum Zeitpunkt des Lesens keine 100% genauen Informationen).
Die fragliche Aufgabe besteht darin, mehr als 1 Million Datenbanktransaktionen pro Stunde durchzuführen.
Ich habe im Internet eine Reihe von Informationen über die Unterschiede zwischen MyISAM und InnoDB gelesen, und MyISAM scheint mir die offensichtliche Wahl für die bestimmte Datenbank / Tabelle zu sein, die ich für diese Aufgabe verwenden werde. Nach dem, was ich zu lesen scheine, ist InnoDB gut, wenn Transaktionen erforderlich sind, da das Sperren auf Zeilenebene unterstützt wird.
Hat jemand Erfahrung mit dieser Art von Last (oder höher)? Ist MyISAM der richtige Weg?
Antworten:
Ich habe diese Frage in einer Tabelle kurz besprochen, damit Sie entscheiden können, ob Sie sich für InnoDB oder MyISAM entscheiden .
Hier ist eine kleine Übersicht darüber, welche DB-Speicher-Engine Sie in welcher Situation verwenden sollten:
Zusammenfassung
quelle
InnoDB - full-text: 5.6.4
?? Es ist ja oder nicht?Ich bin kein Datenbankexperte und spreche nicht aus Erfahrung. Jedoch:
MyISAM-Tabellen verwenden Sperren auf Tabellenebene . Basierend auf Ihren Verkehrsschätzungen haben Sie fast 200 Schreibvorgänge pro Sekunde. Mit MyISAM kann immer nur eine davon ausgeführt werden . Sie müssen sicherstellen, dass Ihre Hardware mit diesen Transaktionen Schritt halten kann, um ein Überlaufen zu vermeiden. Das heißt, eine einzelne Abfrage kann nicht länger als 5 ms dauern.
Das legt für mich nahe, dass Sie eine Speicher-Engine benötigen, die das Sperren auf Zeilenebene unterstützt, dh InnoDB.
Auf der anderen Seite sollte es ziemlich trivial sein, ein paar einfache Skripte zu schreiben, um die Last mit jeder Speicher-Engine zu simulieren, und dann die Ergebnisse zu vergleichen.
quelle
a single query can take no more than 5ms
weil Sie zwei unwahrscheinliche Annahmen gemacht haben; A: Alle Abfragen benötigten dieselbe Tabelle & B: Es war nur 1 Verbindung verfügbar! Ich sollte Sie darüber informieren, dass ein Linux- und MySQL 5.5-Setup mit hohem RAM bis zu 10.000 gleichzeitige Verbindungen unterstützen kann (siehe: dev.mysql.com/doc/refman//5.5/en/too-many-connections.html ).Die Leute reden oft über Leistung, Lesen gegen Schreiben, Fremdschlüssel usw., aber meiner Meinung nach gibt es noch eine andere unverzichtbare Funktion für eine Speicher-Engine: atomare Updates.
Versuche dies:
killall -9 mysqld
einen Absturz simulieren.Leistung ist natürlich wünschenswert, aber kein Datenverlust sollte das übertreffen.
quelle
Bill Karwin
Ich habe mit MySQL an einem hochvolumigen System gearbeitet und sowohl MyISAM als auch InnoDB ausprobiert.
Ich habe festgestellt, dass das Sperren auf Tabellenebene in MyISAM schwerwiegende Leistungsprobleme für unsere Arbeitslast verursacht hat, die sich ähnlich anhören wie Ihre. Leider stellte ich auch fest, dass die Leistung unter InnoDB auch schlechter war als ich gehofft hatte.
Am Ende habe ich das Konfliktproblem gelöst, indem ich die Daten so fragmentiert habe, dass Einfügungen in eine "heiße" Tabelle verschoben wurden und die Auswahl nie abgefragt wurde.
Dies ermöglichte auch das Löschen (die Daten waren zeitkritisch und wir haben nur den Wert von X Tagen beibehalten) in "veralteten" Tabellen, die wiederum nicht von ausgewählten Abfragen berührt wurden. InnoDB scheint bei Massenlöschvorgängen eine schlechte Leistung zu haben. Wenn Sie also Daten löschen möchten, möchten Sie diese möglicherweise so strukturieren, dass sich die alten Daten in einer veralteten Tabelle befinden, die einfach gelöscht werden kann, anstatt Löschvorgänge auszuführen.
Natürlich habe ich keine Ahnung, was Ihre Anwendung ist, aber hoffentlich gibt Ihnen dies einen Einblick in einige der Probleme mit MyISAM und InnoDB.
quelle
Ein bisschen spät zum Spiel ... aber hier ist ein ziemlich umfassender Beitrag, den ich vor einigen Monaten geschrieben habe und in dem die Hauptunterschiede zwischen MYISAM und InnoDB beschrieben werden. Nehmen Sie eine Tasse Kaffee (und vielleicht einen Keks) und genießen Sie.
Der Hauptunterschied zwischen MyISAM und InnoDB besteht in der referenziellen Integrität und den Transaktionen. Es gibt auch andere Unterschiede wie Sperren, Rollbacks und Volltextsuche.
Referenzielle Integrität
Die referenzielle Integrität stellt sicher, dass die Beziehungen zwischen Tabellen konsistent bleiben. Insbesondere bedeutet dies, dass wenn eine Tabelle (z. B. Auflistungen) einen Fremdschlüssel (z. B. Produkt-ID) hat, der auf eine andere Tabelle (z. B. Produkte) verweist, wenn Aktualisierungen oder Löschungen der Tabelle vorgenommen werden, auf die verwiesen wird, diese Änderungen an die Verknüpfung kaskadiert werden Tabelle. In unserem Beispiel werden beim Umbenennen eines Produkts auch die Fremdschlüssel der Verknüpfungstabelle aktualisiert. Wenn ein Produkt aus der Tabelle "Produkte" gelöscht wird, werden auch alle Einträge gelöscht, die auf den gelöschten Eintrag verweisen. Darüber hinaus muss in jeder neuen Liste dieser Fremdschlüssel auf einen gültigen, vorhandenen Eintrag verweisen.
InnoDB ist ein relationales DBMS (RDBMS) und weist daher eine referenzielle Integrität auf, MyISAM jedoch nicht.
Transaktionen & Atomizität
Daten in einer Tabelle werden mit DML-Anweisungen (Data Manipulation Language) wie SELECT, INSERT, UPDATE und DELETE verwaltet. Eine Transaktionsgruppe zwei oder mehr DML-Anweisungen zu einer einzigen Arbeitseinheit, sodass entweder die gesamte Einheit angewendet wird oder keine davon.
MyISAM unterstützt keine Transaktionen, InnoDB jedoch nicht.
Wenn eine Operation während der Verwendung einer MyISAM-Tabelle unterbrochen wird, wird die Operation sofort abgebrochen, und die betroffenen Zeilen (oder sogar Daten in jeder Zeile) bleiben betroffen, auch wenn die Operation nicht abgeschlossen wurde.
Wenn eine Operation während der Verwendung einer InnoDB-Tabelle unterbrochen wird, weil sie Transaktionen mit Atomizität verwendet, wird jede Transaktion, die nicht abgeschlossen wurde, nicht wirksam, da keine Festschreibung erfolgt.
Tabellensperre vs Zeilensperre
Wenn eine Abfrage für eine MyISAM-Tabelle ausgeführt wird, wird die gesamte Tabelle, in der sie abgefragt wird, gesperrt. Dies bedeutet, dass nachfolgende Abfragen erst ausgeführt werden, nachdem die aktuelle abgeschlossen ist. Wenn Sie eine große Tabelle lesen und / oder häufig Lese- und Schreibvorgänge ausgeführt werden, kann dies einen großen Rückstau an Abfragen bedeuten.
Wenn eine Abfrage für eine InnoDB-Tabelle ausgeführt wird, sind nur die betroffenen Zeilen gesperrt. Der Rest der Tabelle bleibt für CRUD-Operationen verfügbar. Dies bedeutet, dass Abfragen gleichzeitig in derselben Tabelle ausgeführt werden können, sofern sie nicht dieselbe Zeile verwenden.
Diese Funktion in InnoDB wird als Parallelität bezeichnet. So groß die Parallelität auch ist, es gibt einen großen Nachteil, der für einen ausgewählten Tabellenbereich gilt, da das Umschalten zwischen Kernel-Threads einen Mehraufwand verursacht und Sie ein Limit für die Kernel-Threads festlegen sollten, um zu verhindern, dass der Server zum Stillstand kommt .
Transaktionen & Rollbacks
Wenn Sie eine Operation in MyISAM ausführen, werden die Änderungen festgelegt. In InnoDB können diese Änderungen rückgängig gemacht werden. Die am häufigsten zur Steuerung von Transaktionen verwendeten Befehle sind COMMIT, ROLLBACK und SAVEPOINT. 1. COMMIT - Sie können mehrere DML-Vorgänge schreiben, die Änderungen werden jedoch nur gespeichert, wenn ein COMMIT durchgeführt wird. 2. ROLLBACK - Sie können alle noch nicht festgeschriebenen Vorgänge verwerfen. 3. SAVEPOINT - Setzt einen Punkt in der Liste von Operationen, auf die eine ROLLBACK-Operation zurückgesetzt werden kann
Verlässlichkeit
MyISAM bietet keine Datenintegrität - Hardwarefehler, unsauberes Herunterfahren und abgebrochene Vorgänge können dazu führen, dass die Daten beschädigt werden. Dies würde eine vollständige Reparatur oder Neuerstellung der Indizes und Tabellen erfordern.
InnoDB verwendet dagegen ein Transaktionsprotokoll, einen Doppelschreibpuffer sowie eine automatische Prüfsumme und Validierung, um Beschädigungen zu vermeiden. Bevor InnoDB Änderungen vornimmt, zeichnet es die Daten vor den Transaktionen in einer Systemtabellenbereichsdatei mit dem Namen ibdata1 auf. Im Falle eines Absturzes würde InnoDB die Wiedergabe dieser Protokolle automatisch wiederherstellen.
FULLTEXT-Indizierung
InnoDB unterstützt die FULLTEXT-Indizierung erst in MySQL Version 5.6.4. Zum Zeitpunkt des Schreibens dieses Beitrags liegt die MySQL-Version vieler Shared Hosting-Anbieter immer noch unter 5.6.4, was bedeutet, dass die FULLTEXT-Indizierung für InnoDB-Tabellen nicht unterstützt wird.
Dies ist jedoch kein gültiger Grund für die Verwendung von MyISAM. Wechseln Sie am besten zu einem Hosting-Anbieter, der aktuelle Versionen von MySQL unterstützt. Nicht dass eine MyISAM-Tabelle, die die FULLTEXT-Indizierung verwendet, nicht in eine InnoDB-Tabelle konvertiert werden kann.
Fazit
Zusammenfassend sollte InnoDB Ihre Standardspeicher-Engine Ihrer Wahl sein. Wählen Sie MyISAM oder andere Datentypen, wenn diese einem bestimmten Bedarf entsprechen.
quelle
INSERT ON DUPLICATE KEY UPDATE
also habe ich MyISAM ausprobiert und jetzt sind es nur noch <1 ms ... Viele Antworten, die ich gesehen habe, sagen das innodb fällt es schwer, mit 'unsortierbaren' (zufälligen Zeichenfolgen) eindeutigen Schlüsseln umzugehen ... Haben Sie dazu irgendwelche Eingaben für uns? Tatsächlich habe ich mich gefragt, welche Auswirkungen MyISAM haben würde, aber Ihre großartige Antwort hat mir klar gemacht, dass dies der richtige Weg für diesen speziellen Fall ist.Für eine Last mit mehr Schreib- und Lesevorgängen profitieren Sie von InnoDB. Da InnoDB eher Zeilen- als Tabellensperren bietet, können Ihre
SELECT
s nicht nur untereinander, sondern auch mit vielenINSERT
s gleichzeitig ausgeführt werden. Wenn Sie jedoch nicht beabsichtigen, SQL-Transaktionen zu verwenden, setzen Sie den InnoDB-Commit-Flush auf 2 ( innodb_flush_log_at_trx_commit ). Dies gibt Ihnen eine Menge Rohleistung zurück, die Sie sonst verlieren würden, wenn Sie Tabellen von MyISAM nach InnoDB verschieben.Erwägen Sie auch das Hinzufügen einer Replikation. Auf diese Weise erhalten Sie eine gewisse Leseskalierung. Da Sie angegeben haben, dass Ihre Lesevorgänge nicht auf dem neuesten Stand sein müssen, können Sie die Replikation etwas zurückfallen lassen. Stellen Sie nur sicher, dass es unter nichts anderem als dem stärksten Verkehr aufholen kann, oder es wird immer zurückbleiben und niemals aufholen. Wenn Sie diesen Weg gehen, empfehle ich Ihnen dringend , das Lesen von den Slaves und die Verwaltung der Replikationsverzögerung auf Ihren Datenbankhandler zu beschränken. Es ist so viel einfacher, wenn der Anwendungscode nichts davon weiß.
Beachten Sie schließlich die unterschiedlichen Tischlasten. Sie haben nicht für alle Tabellen das gleiche Lese- / Schreibverhältnis. Einige kleinere Tabellen mit nahezu 100% Lesevorgängen könnten es sich leisten, MyISAM zu bleiben. Wenn Sie einige Tabellen haben, die fast zu 100% geschrieben sind, können Sie davon profitieren
INSERT DELAYED
, dies wird jedoch nur in MyISAM unterstützt (dieDELAYED
Klausel wird für eine InnoDB-Tabelle ignoriert).Aber Benchmark um sicher zu sein.
quelle
innodb_flush_log_at_trx_commit
?Um die große Auswahl an Antworten zu ergänzen, die die mechanischen Unterschiede zwischen den beiden Motoren abdecken, präsentiere ich eine empirische Geschwindigkeitsvergleichsstudie.
In Bezug auf die reine Geschwindigkeit ist MyISAM nicht immer schneller als InnoDB, aber meiner Erfahrung nach ist es für PURE READ-Arbeitsumgebungen tendenziell um das 2,0- bis 2,5-fache schneller. Dies ist natürlich nicht für alle Umgebungen geeignet. Wie andere bereits geschrieben haben, fehlen MyISAM beispielsweise Transaktionen und Fremdschlüssel.
Ich habe unten ein bisschen Benchmarking durchgeführt - ich habe Python für Loops und die Timeit-Bibliothek für Timing-Vergleiche verwendet. Aus Interesse habe ich auch die Speicher-Engine aufgenommen, die auf der ganzen Linie die beste Leistung bietet, obwohl sie nur für kleinere Tabellen geeignet ist (
The table 'tbl' is full
wenn Sie das MySQL-Speicherlimit überschreiten, treten Sie ständig auf ). Die vier Arten von Auswahl, die ich betrachte, sind:Zuerst habe ich drei Tabellen mit dem folgenden SQL erstellt
In der zweiten und dritten Tabelle wird "InnoDB" und "Speicher" durch "MyISAM" ersetzt.
1) Vanille wählt aus
Abfrage:
SELECT * FROM tbl WHERE index_col = xx
Ergebnis: Unentschieden
Die Geschwindigkeit dieser ist im Großen und Ganzen gleich und wie erwartet linear in der Anzahl der auszuwählenden Spalten. InnoDB scheint etwas schneller als MyISAM zu sein, aber das ist wirklich marginal.
Code:
2) Zählt
Abfrage:
SELECT count(*) FROM tbl
Ergebnis: MyISAM gewinnt
Dieser zeigt einen großen Unterschied zwischen MyISAM und InnoDB - MyISAM (und Speicher) verfolgt die Anzahl der Datensätze in der Tabelle, sodass diese Transaktion schnell und O (1) ist. Die Zeit, die InnoDB zum Zählen benötigt, steigt mit der Tabellengröße in dem von mir untersuchten Bereich superlinear an. Ich vermute, dass viele der in der Praxis beobachteten Beschleunigungen durch MyISAM-Abfragen auf ähnliche Effekte zurückzuführen sind.
Code:
3) Bedingte Auswahl
Abfrage:
SELECT * FROM tbl WHERE value1<0.5 AND value2<0.5 AND value3<0.5 AND value4<0.5
Ergebnis: MyISAM gewinnt
Hier arbeiten MyISAM und Speicher ungefähr gleich und übertreffen InnoDB bei größeren Tabellen um etwa 50%. Dies ist die Art von Abfrage, für die die Vorteile von MyISAM maximiert zu sein scheinen.
Code:
4) Unterauswahl
Ergebnis: InnoDB gewinnt
Für diese Abfrage habe ich einen zusätzlichen Satz von Tabellen für die Unterauswahl erstellt. Jede besteht einfach aus zwei Spalten von BIGINTs, eine mit einem Primärschlüsselindex und eine ohne Index. Aufgrund der großen Tabellengröße habe ich die Speicher-Engine nicht getestet. Der Befehl zum Erstellen einer SQL-Tabelle war
In der zweiten Tabelle wird 'InnoDB' durch 'MyISAM' ersetzt.
In dieser Abfrage belasse ich die Größe der Auswahltabelle bei 1000000 und variiere stattdessen die Größe der unterausgewählten Spalten.
Hier gewinnt die InnoDB leicht. Nachdem wir eine vernünftige Größentabelle erreicht haben, skalieren beide Motoren linear mit der Größe der Unterauswahl. Der Index beschleunigt den MyISAM-Befehl, hat jedoch interessanterweise wenig Einfluss auf die InnoDB-Geschwindigkeit. subSelect.png
Code:
Ich denke, die Botschaft zum Mitnehmen ist, dass Sie, wenn Sie sich wirklich Gedanken über die Geschwindigkeit machen, die von Ihnen durchgeführten Abfragen vergleichen müssen, anstatt Annahmen darüber zu treffen, welche Engine besser geeignet ist.
quelle
my.cnf
Datei nicht für InnoDB optimiert ist. Sie haben nicht erwähnt, wie Ihremy.cnf
Datei aussieht, was wirklich der wichtigste Faktor für die Leistung von InnoDB ist.Etwas abseits des Themas, aber zu Dokumentationszwecken und zur Vollständigkeit möchte ich Folgendes hinzufügen.
Im Allgemeinen führt die Verwendung von InnoDB zu einer viel WENIGER komplexen Anwendung, die wahrscheinlich auch fehlerfreier ist. Da Sie die gesamte referenzielle Integrität (Fremdschlüsseleinschränkungen) in das Datenmodell einfügen können, benötigen Sie nicht annähernd so viel Anwendungscode, wie Sie mit MyISAM benötigen.
Jedes Mal, wenn Sie einen Datensatz einfügen, löschen oder ersetzen, MÜSSEN Sie die Beziehungen überprüfen und pflegen. Wenn Sie beispielsweise ein Elternteil löschen, sollten auch alle Kinder gelöscht werden. Selbst in einem einfachen Blogging-System müssen Sie beispielsweise beim Löschen eines Blogposting-Datensatzes die Kommentardatensätze, Likes usw. löschen. In InnoDB erfolgt dies automatisch durch das Datenbankmodul (wenn Sie die Einschränkungen im Modell angegeben haben ) und erfordert keinen Anwendungscode. In MyISAM muss dies in die Anwendung codiert werden, was auf Webservern sehr schwierig ist. Webserver sind von Natur aus sehr gleichzeitig / parallel. Da diese Aktionen atomar sein sollten und MyISAM keine echten Transaktionen unterstützt, ist die Verwendung von MyISAM für Webserver riskant / fehleranfällig.
Auch in den meisten allgemeinen Fällen wird InnoDB aus mehreren Gründen eine viel bessere Leistung erbringen, da sie in der Lage sind, Sperren auf Datensatzebene im Gegensatz zu Sperren auf Tabellenebene zu verwenden. Nicht nur in Situationen, in denen Schreibvorgänge häufiger sind als Lesevorgänge, sondern auch in Situationen mit komplexen Verknüpfungen in großen Datenmengen. Wir haben eine dreifache Leistungssteigerung festgestellt, indem wir InnoDB-Tabellen gegenüber MyISAM-Tabellen für sehr große Verknüpfungen verwendet haben (dies dauert einige Minuten).
Ich würde sagen, dass InnoDB (unter Verwendung eines 3NF-Datenmodells mit referenzieller Integrität) im Allgemeinen die Standardauswahl bei der Verwendung von MySQL sein sollte. MyISAM sollte nur in ganz bestimmten Fällen verwendet werden. Es wird höchstwahrscheinlich weniger Leistung bringen, was zu einer größeren und fehlerhafteren Anwendung führt.
Nachdem ich das gesagt habe. Datamodelling ist eine Kunst, die unter Webdesignern / -programmierern selten zu finden ist. Nichts für ungut, aber es erklärt, dass MyISAM so oft verwendet wird.
quelle
InnoDB bietet:
In InnoDB können alle Daten in einer Reihe mit Ausnahme von TEXT und BLOB höchstens 8.000 Byte belegen. Für InnoDB ist keine Volltextindizierung verfügbar. In InnoDB werden die COUNT (*) s (wenn WHERE, GROUP BY oder JOIN nicht verwendet werden) langsamer ausgeführt als in MyISAM, da die Zeilenanzahl nicht intern gespeichert wird. InnoDB speichert sowohl Daten als auch Indizes in einer Datei. InnoDB verwendet einen Pufferpool, um sowohl Daten als auch Indizes zwischenzuspeichern.
MyISAM bietet:
MyISAM verfügt über eine Sperre auf Tabellenebene, jedoch keine Sperre auf Zeilenebene. Keine Transaktionen. Keine automatische Wiederherstellung nach einem Absturz, bietet jedoch Funktionen für Reparaturtabellen. Keine Fremdschlüsseleinschränkungen. MyISAM-Tabellen sind im Vergleich zu InnoDB-Tabellen im Allgemeinen kompakter auf der Festplatte. MyISAM-Tabellen können durch Komprimieren mit myisampack bei Bedarf weiter verkleinert werden, sind jedoch schreibgeschützt. MyISAM speichert Indizes in einer Datei und Daten in einer anderen. MyISAM verwendet Schlüsselpuffer zum Zwischenspeichern von Indizes und überlässt die Verwaltung des Daten-Zwischenspeicherns dem Betriebssystem.
Insgesamt würde ich InnoDB für die meisten Zwecke und MyISAM nur für spezielle Zwecke empfehlen. InnoDB ist jetzt die Standard-Engine in neuen MySQL-Versionen.
quelle
Wenn Sie MyISAM verwenden, werden Sie keine Transaktionen pro Stunde ausführen, es sei denn, Sie betrachten jede DML-Anweisung als eine Transaktion (die im Falle eines Absturzes auf keinen Fall dauerhaft oder atomar ist).
Daher denke ich, dass Sie InnoDB verwenden müssen.
300 Transaktionen pro Sekunde klingen nach ziemlich viel. Wenn Sie diese Transaktionen unbedingt benötigen, um bei Stromausfall dauerhaft zu sein, stellen Sie sicher, dass Ihr E / A-Subsystem so viele Schreibvorgänge pro Sekunde problemlos verarbeiten kann. Sie benötigen mindestens einen RAID-Controller mit batteriegepuffertem Cache.
Wenn Sie einen kleinen Haltbarkeitstreffer erzielen können, können Sie InnoDB verwenden, wobei innodb_flush_log_at_trx_commit auf 0 oder 2 gesetzt ist (Details finden Sie in den Dokumenten). Sie können die Leistung verbessern.
Es gibt eine Reihe von Patches, die die Parallelität von Google und anderen erhöhen können. Diese können von Interesse sein, wenn Sie ohne sie immer noch nicht genügend Leistung erzielen können.
quelle
Die Frage und die meisten Antworten sind veraltet .
Ja, es ist eine Geschichte alter Frauen, dass MyISAM schneller als InnoDB ist. Beachten Sie das Datum der Frage: 2008; es ist jetzt fast ein Jahrzehnt später. InnoDB hat seitdem erhebliche Leistungsschritte gemacht.
Die dramatische Graph war für den einen Fall , in dem MyISAM gewinnt:
COUNT(*)
ohne eineWHERE
Klausel. Aber verbringst du deine Zeit wirklich damit?Wenn Sie einen Parallelitätstest durchführen, ist es sehr wahrscheinlich, dass InnoDB gewinnt, auch gegen
MEMORY
.Wenn Sie während des Benchmarking Schreibvorgänge
SELECTs
ausführenMEMORY
, verlieren MyISAM und wahrscheinlich aufgrund von Sperren auf Tabellenebene.Tatsächlich ist Oracle sich so sicher, dass InnoDB besser ist, als dass MyISAM von 8.0 so gut wie entfernt wurde.
Die Frage wurde früh in den Tagen von 5.1 geschrieben. Seitdem wurden diese Hauptversionen als "Allgemeine Verfügbarkeit" gekennzeichnet:
Fazit: Verwenden Sie MyISAM nicht
quelle
Schauen Sie sich auch einige Drop-In-Ersetzungen für MySQL selbst an:
MariaDB
http://mariadb.org/
MariaDB ist ein Datenbankserver, der Drop-In-Ersatzfunktionen für MySQL bietet. MariaDB wurde von einigen der ursprünglichen Autoren von MySQL mit Unterstützung der breiteren Community von Entwicklern von Free- und Open-Source-Software erstellt. Zusätzlich zu den Kernfunktionen von MySQL bietet MariaDB eine Reihe von Funktionserweiterungen, darunter alternative Speicher-Engines, Serveroptimierungen und Patches.
Percona Server
https://launchpad.net/percona-server
Ein erweiterter Drop-In-Ersatz für MySQL mit besserer Leistung, verbesserter Diagnose und zusätzlichen Funktionen.
quelle
Bitte beachten Sie, dass meine formale Ausbildung und Erfahrung bei Oracle liegt, während meine Arbeit mit MySQL ganz persönlich und in meiner Freizeit war. Wenn ich also Dinge sage, die für Oracle gelten, für MySQL jedoch nicht, entschuldige ich mich. Während die beiden Systeme viel gemeinsam haben, ist die relationale Theorie / Algebra dieselbe und relationale Datenbanken sind immer noch relationale Datenbanken, es gibt immer noch viele Unterschiede !!
Ich mag besonders (sowie das Sperren auf Zeilenebene), dass InnoDB transaktionsbasiert ist, was bedeutet, dass Sie möglicherweise mehrmals für einen "Vorgang" Ihrer Webanwendung aktualisieren / einfügen / erstellen / ändern / löschen / usw. Das Problem besteht darin, dass Sie, wenn nur einige dieser Änderungen / Vorgänge festgeschrieben werden, andere jedoch nicht (abhängig vom spezifischen Design der Datenbank), meistens eine Datenbank mit widersprüchlichen Daten / Strukturen erhalten.
Hinweis: Bei Oracle werden create / alter / drop-Anweisungen als "DDL" -Anweisungen (Data Definition) bezeichnet und lösen implizit ein Commit aus. Anweisungen zum Einfügen / Aktualisieren / Löschen mit der Bezeichnung "DML" (Data Manipulation) werden nicht automatisch festgeschrieben, sondern nur, wenn eine DDL, ein Festschreiben oder ein Beenden / Beenden ausgeführt wird (oder wenn Sie Ihre Sitzung auf "Auto-Commit" setzen oder wenn Ihr Client automatisch festschreibt). Wenn Sie mit Oracle arbeiten, müssen Sie sich dessen unbedingt bewusst sein, aber ich bin mir nicht sicher, wie MySQL mit den beiden Arten von Anweisungen umgeht. Aus diesem Grund möchte ich klarstellen, dass ich mir bei MySQL nicht sicher bin. nur mit Oracle.
Ein Beispiel dafür, wann transaktionsbasierte Engines sich auszeichnen:
Nehmen wir an, ich oder Sie befinden sich auf einer Webseite, um sich für eine kostenlose Veranstaltung anzumelden. Einer der Hauptzwecke des Systems besteht darin, nur bis zu 100 Personen die Anmeldung zu ermöglichen, da dies die Begrenzung der Sitzplätze darstellt Für das Event. Sobald 100 Anmeldungen erreicht sind, würde das System weitere Anmeldungen deaktivieren, zumindest bis andere abbrechen.
In diesem Fall gibt es möglicherweise einen Tisch für Gäste (Name, Telefon, E-Mail usw.) und einen zweiten Tisch, an dem die Anzahl der angemeldeten Gäste erfasst wird. Wir haben also zwei Operationen für eine "Transaktion". Angenommen, nach dem Hinzufügen der Gastinformationen zur GUESTS-Tabelle tritt ein Verbindungsverlust oder ein Fehler mit derselben Auswirkung auf. Die GUESTS-Tabelle wurde aktualisiert (eingefügt), aber die Verbindung wurde unterbrochen, bevor die "verfügbaren Plätze" aktualisiert werden konnten.
Jetzt haben wir einen Gast zum Gästetisch hinzugefügt, aber die Anzahl der verfügbaren Plätze ist jetzt falsch (zum Beispiel ist der Wert 85, wenn er tatsächlich 84 ist).
Natürlich gibt es viele Möglichkeiten, dies zu handhaben, z. B. die Verfolgung verfügbarer Plätze mit "100 minus Anzahl der Zeilen in der Gästetabelle" oder einen Code, der überprüft, ob die Informationen konsistent sind usw. Aber mit einer transaktionsbasierten Datenbank Bei einer Engine wie InnoDB werden entweder ALLE Vorgänge festgeschrieben oder KEINE von ihnen. Dies kann in vielen Fällen hilfreich sein, aber wie gesagt, es ist nicht der EINZIGE Weg, um sicher zu sein, nein (ein guter Weg, der jedoch von der Datenbank und nicht vom Programmierer / Drehbuchautor gehandhabt wird).
Das ist alles, was "transaktionsbasiert" in diesem Zusammenhang im Wesentlichen bedeutet, es sei denn, ich vermisse etwas - dass entweder die gesamte Transaktion so erfolgreich ist, wie sie sollte, oder dass nichts geändert wird, da nur teilweise Änderungen das SEVERE-Chaos geringfügig beeinträchtigen können Datenbank, vielleicht sogar beschädigt ...
Aber ich werde es noch einmal sagen, es ist nicht der einzige Weg, um ein Durcheinander zu vermeiden. Aber es ist eine der Methoden, die die Engine selbst handhabt, sodass Sie sich nur noch darum kümmern müssen, ob die Transaktion erfolgreich war oder nicht, und was mache ich, wenn nicht (z. B. erneut versuchen), anstatt manuell Schreiben von Code, um ihn "manuell" von außerhalb der Datenbank zu überprüfen, und viel mehr Arbeit für solche Ereignisse.
Zum Schluss noch ein Hinweis zum Sperren von Tabellen und zum Sperren von Zeilen:
HAFTUNGSAUSSCHLUSS: Ich kann mich in allem, was in Bezug auf MySQL folgt, irren, und die hypothetischen / Beispielsituationen sind Dinge, die untersucht werden müssen, aber ich kann mich irren, was genau möglich ist, mit MySQL Korruption zu verursachen. Die Beispiele sind jedoch in der allgemeinen Programmierung sehr real, selbst wenn MySQL über mehr Mechanismen verfügt, um solche Dinge zu vermeiden ...
Wie dem auch sei, ich bin ziemlich zuversichtlich , mit denen bei der Vereinbarung , die argumentiert haben , dass , wie viele Verbindungen gleichzeitig erlaubt ist nicht eine gesperrte Tabelle umgehen. In der Tat sind mehrere Verbindungen der gesamte Punkt, um eine Tabelle zu sperren !! Damit andere Prozesse / Benutzer / Apps die Datenbank nicht durch gleichzeitige Änderungen beschädigen können.
Wie würden zwei oder mehr Verbindungen, die in derselben Zeile arbeiten, einen WIRKLICH SCHLECHTEN TAG für Sie bedeuten? Angenommen, es gibt zwei Prozesse, die beide denselben Wert in derselben Zeile aktualisieren möchten / müssen, beispielsweise weil die Zeile eine Aufzeichnung einer Bustour ist und jeder der beiden Prozesse gleichzeitig die "Fahrer" oder "verfügbaren_Sitze" aktualisieren möchte. Feld als "der aktuelle Wert plus 1."
Lassen Sie uns dies hypothetisch Schritt für Schritt tun:
Ich bin mir nicht sicher, ob sich zwei Verbindungen so vermischen könnten, beide lesen, bevor der erste schreibt ... Aber wenn nicht, dann würde ich immer noch ein Problem sehen mit:
Zumindest bei Oracle-Datenbanken gibt es auch Isolationsstufen, die ich nicht mit Paraphrasen verschwenden werde. Hier ist ein guter Artikel zu diesem Thema, und jede Isolationsstufe hat ihre Vor- und Nachteile, die damit einhergehen, wie wichtig transaktionsbasierte Engines in einer Datenbank sein können ...
Schließlich gibt es in MyISAM möglicherweise andere Sicherheitsvorkehrungen als Fremdschlüssel und transaktionsbasierte Interaktion. Zum einen gibt es die Tatsache, dass eine ganze Tabelle gesperrt ist, was es weniger wahrscheinlich macht, dass Transaktionen / FKs benötigt werden .
Und leider, wenn Sie sich dieser Parallelitätsprobleme bewusst sind, können Sie auf Nummer sicher gehen und einfach Ihre Anwendungen schreiben und Ihre Systeme so einrichten, dass solche Fehler nicht möglich sind (Ihr Code ist dann verantwortlich und nicht die Datenbank selbst). Meiner Meinung nach würde ich jedoch sagen, dass es immer am besten ist, so viele Sicherheitsvorkehrungen wie möglich zu treffen, defensiv zu programmieren und sich immer bewusst zu sein, dass menschliches Versagen unmöglich vollständig zu vermeiden ist. Es passiert jedem, und jeder, der sagt, dass er dagegen immun ist, muss lügen oder hat nicht mehr getan, als eine "Hello World" -Anwendung / ein Skript zu schreiben. ;-);
Ich hoffe, dass EINIGES davon für jemanden hilfreich ist, und noch mehr, ich hoffe, dass ich nicht gerade jetzt ein Schuldiger von Annahmen war und ein Mensch im Irrtum war !! Ich entschuldige mich, wenn ja, aber die Beispiele sind gut zu überlegen, das Risiko zu untersuchen und so weiter, auch wenn sie in diesem speziellen Kontext nicht potenziell sind.
Fühlen Sie sich frei, mich zu korrigieren, diese "Antwort" zu bearbeiten und sogar abzustimmen. Versuchen Sie einfach, sich zu verbessern, anstatt eine schlechte Annahme von mir mit einer anderen zu korrigieren. ;-);
Dies ist meine erste Antwort, bitte verzeihen Sie die Länge aufgrund aller Haftungsausschlüsse usw. Ich möchte einfach nicht arrogant klingen, wenn ich nicht absolut sicher bin!
quelle
Ich denke, dies ist ein ausgezeichneter Artikel zur Erklärung der Unterschiede und wann Sie einen über den anderen verwenden sollten: http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB
quelle
Nach meiner Erfahrung war MyISAM die bessere Wahl, solange Sie keine DELETEs, UPDATEs, viele einzelne INSERT-Transaktionen, Transaktionen und Volltextindizierungen ausführen. Übrigens, CHECK TABLE ist schrecklich. Da die Tabelle in Bezug auf die Anzahl der Zeilen älter wird, wissen Sie nicht, wann sie enden wird.
quelle
Ich habe herausgefunden, dass Myisam, obwohl es Sperrenkonflikte gibt, in den meisten Szenarien aufgrund des verwendeten Schlosserfassungsschemas immer noch schneller als InnoDb ist. Ich habe Innodb mehrmals ausprobiert und greife aus dem einen oder anderen Grund immer auf MyIsam zurück. Auch InnoDB kann bei großen Schreiblasten sehr CPU-intensiv sein.
quelle
Jede Anwendung verfügt über ein eigenes Leistungsprofil für die Verwendung einer Datenbank, das sich wahrscheinlich im Laufe der Zeit ändert.
Das Beste, was Sie tun können, ist, Ihre Optionen zu testen. Das Wechseln zwischen MyISAM und InnoDB ist trivial. Laden Sie also einige Testdaten und feuern Sie jmeter gegen Ihre Site und sehen Sie, was passiert.
quelle
Ich habe versucht, zufällige Daten in MyISAM- und InnoDB-Tabellen einzufügen. Das Ergebnis war ziemlich schockierend. MyISAM benötigte ein paar Sekunden weniger zum Einfügen von 1 Million Zeilen als InnoDB für nur 10 Tausend!
quelle
myisam ist ein NOGO für diese Art von Workload (Schreibvorgänge mit hoher Parallelität). Ich habe nicht so viel Erfahrung mit innodb (habe es dreimal getestet und in jedem Fall festgestellt, dass die Leistung schlecht war, aber es ist eine Weile her seit dem letzten Test), wenn Sie Ich bin nicht gezwungen, MySQL auszuführen. Versuchen Sie es mit Postgres, da es gleichzeitige Schreibvorgänge VIEL besser handhabt
quelle
Kurz gesagt, InnoDB ist gut, wenn Sie an etwas arbeiten, das eine zuverlässige Datenbank benötigt, die viele INSERT- und UPDATE-Anweisungen verarbeiten kann.
und MyISAM ist gut, wenn Sie eine Datenbank benötigen, die meistens viele Leseanweisungen (SELECT) anstelle von Schreibanweisungen (INSERT und UPDATES) benötigt, wenn man den Nachteil der Tabellensperre berücksichtigt.
Vielleicht möchten Sie auschecken.
Vor- und Nachteile von InnoDB
Vor- und Nachteile von MyISAM
quelle
Ich weiß, dass dies nicht beliebt sein wird, aber hier ist:
myISAM bietet keine Unterstützung für Datenbankdaten wie Transaktionen und referenzielle Integrität, was häufig zu fehlerhaften / fehlerhaften Anwendungen führt. Sie können nicht die richtigen Grundlagen für das Datenbankdesign lernen, wenn diese nicht einmal von Ihrer Datenbank-Engine unterstützt werden.
Wenn Sie in der Datenbankwelt keine referenzielle Integrität oder Transaktionen verwenden, ist dies so, als würden Sie in der Software-Welt keine objektorientierte Programmierung verwenden.
InnoDB existiert jetzt, benutze das stattdessen! Sogar MySQL-Entwickler haben endlich zugestanden, dies in neueren Versionen auf die Standard-Engine zu ändern, obwohl myISAM die ursprüngliche Engine war, die in allen Legacy-Systemen die Standardeinstellung war.
Nein, es spielt keine Rolle, ob Sie lesen oder schreiben oder welche Leistungsaspekte Sie haben. Die Verwendung von myISAM kann zu einer Reihe von Problemen führen, z. B. dem, auf das ich gerade gestoßen bin: Ich habe eine Datenbanksynchronisierung durchgeführt und gleichzeitig eine andere Person Zugriff auf eine Anwendung, die auf eine auf myISAM festgelegte Tabelle zugegriffen hat. Aufgrund der fehlenden Transaktionsunterstützung und der allgemein schlechten Zuverlässigkeit dieser Engine stürzte die gesamte Datenbank ab und ich musste mysql manuell neu starten!
In den letzten 15 Jahren meiner Entwicklung habe ich viele Datenbanken und Engines verwendet. myISAM stürzte in dieser Zeit ungefähr ein Dutzend Mal auf mich ab, andere Datenbanken nur einmal! Und das war eine Microsoft SQL-Datenbank, in der einige Entwickler fehlerhaften CLR-Code (Common Language Runtime - im Grunde C # -Code, der in der Datenbank ausgeführt wird) geschrieben haben. Es war übrigens nicht genau der Fehler des Datenbankmoduls.
Ich stimme den anderen Antworten hier zu, die besagen, dass hochwertige Hochverfügbarkeits- und Hochleistungsanwendungen myISAM nicht verwenden sollten, da es nicht funktioniert, nicht robust oder stabil genug ist, um eine frustrationsfreie Erfahrung zu erzielen. Weitere Einzelheiten finden Sie in der Antwort von Bill Karwin.
PS Ich muss es lieben, wenn myISAM-Fanboys abstimmen, aber ich kann dir nicht sagen, welcher Teil dieser Antwort falsch ist.
quelle
Für dieses Verhältnis von Lesen / Schreiben würde InnoDB vermutlich eine bessere Leistung erbringen. Da Sie mit schmutzigen Lesevorgängen einverstanden sind, können Sie (wenn Sie es sich leisten) auf einen Slave replizieren und alle Ihre Lesevorgänge an den Slave gehen lassen. Ziehen Sie auch in Betracht, nicht nur einen Datensatz, sondern jeweils in großen Mengen einzufügen.
quelle
Fast jedes Mal, wenn ich ein neues Projekt starte, google ich dieselbe Frage, um zu sehen, ob ich neue Antworten finde.
Es läuft schließlich darauf hinaus - ich nehme die neueste Version von MySQL und führe Tests durch.
Ich habe Tabellen, in denen ich Schlüssel- / Wertsuchen durchführen möchte ... und das ist alles. Ich muss den Wert (0-512 Bytes) für einen Hash-Schlüssel erhalten. Es gibt nicht viele Transaktionen in dieser Datenbank. Die Tabelle wird gelegentlich (in ihrer Gesamtheit) aktualisiert, jedoch mit 0 Transaktionen.
Wir sprechen hier also nicht von einem komplexen System, sondern von einer einfachen Suche. Und wie wir (abgesehen davon, dass der Tabellen-RAM resident ist) die Leistung optimieren können.
Ich mache auch Tests mit anderen Datenbanken (dh NoSQL), um zu sehen, ob es irgendwo einen Vorteil gibt. Der größte Vorteil, den ich gefunden habe, liegt in der Schlüsselzuordnung, aber was die Suche angeht, übertrifft MyISAM derzeit alle.
Ich würde zwar keine Finanztransaktionen mit MyISAM-Tabellen durchführen, aber für einfache Suchvorgänge sollten Sie es testen. In der Regel 2x bis 5x die Abfragen / Sek.
Testen Sie es, ich begrüße die Debatte.
quelle
Wenn es sich um 70% Einfügungen und 30% Lesevorgänge handelt, ähnelt dies eher der InnoDB-Seite.
quelle
Fazit: Wenn Sie offline mit ausgewählten Datenblöcken arbeiten, bietet Ihnen MyISAM wahrscheinlich bessere (viel bessere) Geschwindigkeiten.
Es gibt Situationen, in denen MyISAM unendlich effizienter als InnoDB ist: Wenn große Datenabbilder offline bearbeitet werden (aufgrund der Tabellensperre).
Beispiel: Ich habe eine CSV-Datei (15 Millionen Datensätze) von NOAA konvertiert, die VARCHAR-Felder als Schlüssel verwendet. InnoDB dauerte ewig, selbst wenn große Speicherblöcke verfügbar waren.
Dies ist ein Beispiel für die CSV (erstes und drittes Feld sind Schlüssel).
Da ich ein Batch-Offline-Update der beobachteten Wetterphänomene ausführen muss, verwende ich die MyISAM-Tabelle zum Empfangen von Daten und führe JOINS auf den Schlüsseln aus, damit ich die eingehende Datei bereinigen und VARCHAR-Felder durch INT-Schlüssel ersetzen kann (die sich darauf beziehen externe Tabellen, in denen die ursprünglichen VARCHAR-Werte gespeichert sind).
quelle