892 Stimmen

MyISAM gegenüber InnoDB

Ich arbeite an einem Projekt, bei dem viel in Datenbanken geschrieben wird, würde ich sagen ( 70% Beilagen und 30% Lesestoff ). Dieses Verhältnis würde auch Aktualisierungen einschließen, die ich als ein Lesen und ein Schreiben betrachte. Die Lesevorgänge können unsauber sein (z. B. benötige ich keine 100%ig genauen Informationen zum Zeitpunkt des Lesens).
Die betreffende Aufgabe wird über 1 Million Datenbanktransaktionen pro Stunde umfassen.

Ich habe eine Reihe von Sachen auf dem Web über die Unterschiede zwischen MyISAM und InnoDB gelesen, und MyISAM scheint wie die offensichtliche Wahl zu mir für die bestimmte Datenbank/Tabellen, die ich für diese Aufgabe verwenden werden. Nach dem, was ich zu lesen scheine, ist InnoDB gut, wenn Transaktionen benötigt werden, da Sperren auf Zeilenebene unterstützt wird.

Hat jemand Erfahrung mit dieser Art von Belastung (oder höher)? Ist MyISAM der richtige Weg?

14 Stimmen

Le MySQL-Leistungs-Blog ist eine großartige Quelle für diese Art von Dingen.

3 Stimmen

Dies hängt ein wenig davon ab, ob Ihr System OLTP- oder eher Datawarehouse-orientiert ist (wo die meisten Schreibvorgänge in großen Mengen erfolgen).

38 Stimmen

MyISAM unterstützt kein Row-Locking, keine Transaktionen, es unterstützt nicht einmal Fremdschlüssel... verdammt, da es keine SÄURE kann man kaum noch von einer richtigen Datenbank sprechen! Das ist der Grund, warum InnoDB seit MySQL 5.5 die Standard-Engine ist... aber, aus welchem Grund auch immer, ist MyISAM weiterhin die Standard-Engine für Tabellen, die mit PhpMyAdmin erstellt werden, so dass viele Amateur-Datenbanken seitdem auf MyISAM laufen.

25voto

MarkR Punkte 60862

Wenn Sie MyISAM verwenden, werden Sie nicht a Transaktionen pro Stunde, es sei denn, Sie betrachten jede DML-Anweisung als eine Transaktion (die im Falle eines Absturzes ohnehin nicht dauerhaft oder atomar ist).

Daher denke ich, dass Sie InnoDB verwenden müssen.

300 Transaktionen pro Sekunde sind eine ganze Menge. Wenn Sie unbedingt wollen, dass diese Transaktionen auch bei einem Stromausfall Bestand haben, sollten Sie sicherstellen, dass Ihr E/A-Subsystem so viele Schreibvorgänge pro Sekunde problemlos bewältigen kann. Sie benötigen mindestens einen RAID-Controller mit batteriegepuffertem Cache.

Wenn Sie eine kleine Haltbarkeit Hit nehmen können, könnten Sie InnoDB mit innodb_flush_log_at_trx_commit auf 0 oder 2 gesetzt (siehe Docs für Details), können Sie Leistung verbessern.

Es gibt eine Reihe von Patches von Google und anderen, die die Gleichzeitigkeit erhöhen können - diese können von Interesse sein, wenn Sie ohne diese Patches keine ausreichende Leistung erhalten.

12voto

Refiner Punkte 129

Sehen Sie sich auch einige Drop-in-Ersatzlösungen für MySQL selbst an:

MariaDB

http://mariadb.org/

MariaDB ist ein Datenbankserver, der MySQL durch eine Drop-in-Ersatzfunktionalität ersetzt. MariaDB wird von einigen der ursprünglichen MySQL-Autoren mit Unterstützung der breiteren Gemeinschaft der Free- und Open-Source-Software-Entwickler entwickelt. Zusätzlich zu den Kernfunktionen von MySQL bietet MariaDB eine Vielzahl 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, verbesserten Diagnosen und zusätzlichen Funktionen.

12voto

Arembjorn Punkte 121

Bitte beachten Sie daß meine formale Ausbildung und Erfahrung mit Oracle ist, während meine Arbeit mit MySQL ausschließlich persönlich und in meiner Freizeit stattfand. Wenn ich also Dinge sage, die auf Oracle zutreffen, aber nicht auf MySQL, bitte ich um Entschuldigung. Obwohl die beiden Systeme viel gemeinsam haben, die relationale Theorie/Algebra dieselbe ist und relationale Datenbanken immer noch relationale Datenbanken sind, gibt es doch eine Menge Unterschiede!!!

Besonders gut gefällt mir (neben dem Sperren auf Zeilenebene), dass InnoDB transaktionsbasiert ist, was bedeutet, dass Sie bei einer "Operation" Ihrer Webanwendung möglicherweise mehrmals aktualisieren/einfügen/erstellen/verändern/verwerfen/etc. Das Problem, das sich daraus ergibt, ist, dass wenn nur einige Wenn einige dieser Änderungen/Vorgänge übertragen werden, andere jedoch nicht, haben Sie in den meisten Fällen (je nach dem spezifischen Design der Datenbank) eine Datenbank mit widersprüchlichen Daten/Strukturen.

Nota: Bei Oracle werden die Anweisungen zum Erstellen/Ändern/Löschen als DDL-Anweisungen (Data Definition) bezeichnet und lösen implizit eine Übertragung aus. Anweisungen zum Einfügen/Aktualisieren/Löschen von Daten werden als "DML" (Data Manipulation) bezeichnet und sind no automatisch übertragen, aber nur, wenn eine DDL, ein Commit oder ein Exit/Quit durchgeführt wird (oder wenn Sie Ihre Sitzung auf "Auto-Commit" einstellen oder wenn Ihr Client Auto-Commits durchführt). Bei der Arbeit mit Oracle muss man sich dessen unbedingt bewusst sein, aber ich bin mir nicht sicher, wie MySQL die beiden Arten von Anweisungen handhabt. Aus diesem Grund möchte ich klarstellen, dass ich mir darüber nicht sicher bin, wenn es um MySQL geht; nur bei Oracle.

Ein Beispiel dafür, wie sich transaktionsbasierte Engines auszeichnen:

Angenommen, ich oder Sie befinden sich auf einer Webseite, auf der Sie sich für eine kostenlose Veranstaltung anmelden können, und einer der Hauptzwecke des Systems besteht darin, dass sich nur bis zu 100 Personen anmelden können, da dies die Höchstzahl der Plätze für die Veranstaltung ist. Sobald die Zahl von 100 Anmeldungen erreicht ist, würde das System weitere Anmeldungen verhindern, zumindest bis andere absagen.

In diesem Fall kann es eine Tabelle für die Gäste geben (Name, Telefon, E-Mail usw.) und eine zweite Tabelle, in der die Anzahl der angemeldeten Gäste erfasst wird. Wir haben also zwei Vorgänge für eine "Transaktion". Nehmen wir nun an, dass es nach dem Hinzufügen der Gästeinformationen zur Tabelle GÄSTE zu einem Verbindungsverlust oder einem Fehler mit denselben Auswirkungen kommt. Die Tabelle GÄSTE 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 (z. B. ist der Wert 85, obwohl er eigentlich 84 ist).

Natürlich Es gibt viele Möglichkeiten, dies zu handhaben, z. B. die Verfolgung der verfügbaren Plätze mit "100 minus Anzahl der Zeilen in der Gästetabelle" oder ein Code, der die Konsistenz der Informationen überprüft, usw. .... Aber mit einer transaktionsbasierten Datenbank-Engine wie InnoDB kann entweder ALLE der Vorgänge gebunden sind, oder KEINE von ihnen sind. Dies kann in vielen Fällen hilfreich sein, aber wie gesagt, es ist nicht der einzige Weg, um sicher zu sein, nein (ein netter Weg, der jedoch von der Datenbank und nicht vom Programmierer/Skriptschreiber gehandhabt wird).

Das ist alles, was "transaktionsbasiert" in diesem Zusammenhang bedeutet, es sei denn, ich übersehe etwas - dass entweder die gesamte Transaktion erfolgreich ist, wie sie sollte, oder nichts geändert wird, da eine nur teilweise Änderung die Datenbank geringfügig bis SCHWER beeinträchtigen und sie vielleicht sogar beschädigen könnte...

Aber ich sage es noch einmal: Es ist nicht der einzige Weg, um eine Sauerei zu vermeiden. Aber es ist eine der Methoden, die der Motor selbst behandelt, so dass Sie Code / Skript mit nur brauchen, um über "war die Transaktion erfolgreich oder nicht, und was tun, wenn nicht (z. B. erneut versuchen)," statt manuell Code zu schreiben, um es zu überprüfen "manuell" von außerhalb der Datenbank, und tun eine Menge mehr Arbeit für solche Ereignisse.

Abschließend noch ein Hinweis zum Tabellen- und Zeilen-Locking:

DISCLAIMER: Es kann sein, dass ich in allem, was im Folgenden in Bezug auf MySQL steht, falsch liege, und die hypothetischen/beispielhaften Situationen sind Dinge, die man untersuchen sollte, aber es kann sein, dass ich falsch liege, was genau ist es möglich, dass MySQL beschädigt wird. Die Beispiele sind jedoch sehr real in der allgemeinen Programmierung, auch wenn MySQL mehr Mechanismen hat, um solche Dinge zu vermeiden...

Jedenfalls bin ich ziemlich sicher, dass ich mit denjenigen übereinstimme, die argumentiert haben, dass die Anzahl der gleichzeitig zulässigen Verbindungen tut no um einen verschlossenen Tisch herum arbeiten. In der Tat, mehrere Verbindungen sind der eigentliche Sinn des Schließens eines Tisches!! So wird verhindert, dass andere Prozesse/Benutzer/Anwendungen die Datenbank durch gleichzeitige Änderungen beschädigen können.

Inwiefern würden zwei oder mehr Verbindungen, die an derselben Reihe arbeiten, einen WIRKLICH SCHLECHTEN TAG für Sie bedeuten? Angenommen, es gibt zwei Prozesse, die beide denselben Wert in derselben Zeile aktualisieren wollen/müssen, z. B. weil es sich bei der Zeile um einen Datensatz einer Bustour handelt, und jeder der beiden Prozesse möchte gleichzeitig das Feld "riders" oder "available_seats" als "den aktuellen Wert plus 1" aktualisieren.

Lassen Sie uns dies hypothetisch, Schritt für Schritt tun:

  1. Prozess eins liest den aktuellen Wert, sagen wir, er ist leer, also bisher '0'.
  2. Prozess zwei liest ebenfalls den aktuellen Wert, der immer noch 0 ist.
  3. Prozess eins schreibt (aktuell + 1), was 1 ist.
  4. Prozess zwei sollte 2 zu schreiben, aber da es den aktuellen Wert gelesen hat antes de process one den neuen Wert schreiben, schreibt er ebenfalls 1 in die Tabelle.

Ich bin nicht sicher dass sich zwei Verbindungen auf diese Weise vermischen könnten, wobei beide lesen, bevor die erste schreibt... Aber wenn nicht, dann würde ich immer noch ein Problem mit sehen:

  1. Prozess eins liest den aktuellen Wert, der 0 ist.
  2. Prozess eins schreibt (aktuell + 1), was 1 ist.
  3. Prozess zwei liest nun den aktuellen Wert. Prozess eins hat zwar geschrieben (aktualisiert), aber die Daten noch nicht festgeschrieben. Daher kann nur dieser Prozess den neuen Wert lesen, den er aktualisiert hat, während alle anderen den älteren Wert sehen, bis eine Festschreibung erfolgt.

Außerdem gibt es, zumindest bei Oracle-Datenbanken, Isolationsebenen, die zu umschreiben ich keine Zeit verschwenden will. Hier ist ein guter Artikel zu diesem Thema, und jede Isolationsebene hat ihre Vor- und Nachteile, die damit zusammenhängen, wie wichtig transaktionsbasierte Engines in einer Datenbank sein können...

Schließlich gibt es in MyISAM wahrscheinlich andere Sicherheitsvorkehrungen als fremde Schlüssel und eine transaktionsbasierte Interaktion. Zum einen ist eine ganze Tabelle gesperrt, was es weniger wahrscheinlich macht, dass Transaktionen/FKs benötigt .

Und wenn Sie sich dieser Gleichzeitigkeitsprobleme bewusst sind, können Sie auf Nummer sicher gehen und Ihre Anwendungen so 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 ist es jedoch immer am besten, so viele Sicherheitsvorkehrungen wie möglich zu treffen, defensiv zu programmieren und sich immer bewusst zu sein, dass menschliches Versagen nicht vollständig zu vermeiden ist. Es passiert jedem, und jeder, der sagt, er sei immun dagegen, 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 hoffe ich, dass ich nicht gerade jetzt ein Schuldiger von Annahmen und ein Mensch im Irrtum gewesen bin!!! Ich bitte um Entschuldigung, falls dies der Fall sein sollte, aber die Beispiele sind gut, um darüber nachzudenken, das Risiko zu erforschen usw., auch wenn sie in diesem speziellen Zusammenhang nicht in Frage kommen.

Sie können mich gerne korrigieren, diese "Antwort" bearbeiten oder sie sogar ablehnen. Versuchen Sie bitte nur, sich zu verbessern, anstatt eine falsche Annahme von mir mit einer anderen zu korrigieren ;-)

Dies ist meine erste Antwort, also verzeihen Sie bitte die Länge aufgrund der vielen Haftungsausschlüsse usw... Ich möchte nur nicht arrogant klingen, wenn ich mir nicht absolut sicher bin!

11voto

jsherk Punkte 121

Ich denke, dies ist ein hervorragender Artikel, der die Unterschiede erklärt und zeigt, wann man den einen und wann den anderen verwenden sollte: http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB

5voto

Ricardo Punkte 1351

Ich habe herausgefunden, dass, obwohl Myisam Sperrkonflikte hat, ist es immer noch schneller als InnoDb in den meisten Szenarien wegen der schnellen Sperre Akquisition Schema es verwendet. Ich habe mehrmals Innodb ausprobiert und bin aus dem einen oder anderen Grund immer wieder auf MyIsam zurückgefallen. Auch InnoDB kann bei großen Schreiblasten sehr CPU-intensiv sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X