
Ich habe eine MyISAM-Tabelle, die derzeit etwa 54 Millionen Datensätze enthält und 20 GB groß ist. Bei der Entwicklung dieser Datenbank wurden schlechte Entscheidungen getroffen. Ich bin kein Datenbankprofi, aber da in diese Tabelle ständig geschrieben und sie nur selten abgefragt wird, wäre InnoDB wohl die bessere Wahl gewesen. Das Problem ist, dass diese Tabelle fast immer zum Schreiben verfügbar sein muss. Eines der Felder ist ein Feld mit Zeitstempel. Die Datensätze reichen 5 Jahre zurück – ich muss nur die letzten 6 Monate aufbewahren. Ich habe einige Löschvorgänge versucht, es dauert etwa 20 Minuten, um 200.000 Zeilen zu löschen, währenddessen die Tabelle gesperrt ist und nicht beschrieben werden kann. Hat jemand Vorschläge, wie ich die Größe dieser Tabelle reduzieren kann, ohne dass sie mehrere Stunden lang gesperrt ist? Gibt es eine schnellere Möglichkeit, die nicht benötigten Zeilen zu löschen? Ich habe noch nie eine MyISAM-Tabelle in eine InnoDB-Tabelle konvertiert. Ist das ein langwieriger Prozess?
Antwort1
Ich hatte endlich Zeit, dieses Projekt noch einmal zu überdenken, und der Vollständigkeit halber wollte ich hier posten, was ich letztendlich gemacht habe. Das ursprüngliche Problem, dass DELETE FROM so lange dauerte, hängt meiner Meinung nach damit zusammen, wie ich die zu löschenden Zeilen angegeben habe. Ich habe eine Anweisung ähnlich wie
DELETE FROM table WHERE starttime < 20150101 limit 200000;
Das Startzeitfeld ist eigentlich ein DATETIME. Ich habe schließlich eine neue Tabelle erstellt mit
CREATE TABLE new_table LIKE existing_table;
und dann die Engine der neuen Tabelle ändern
ALTER TABLE new_table ENGINE=InnoDB;
und dann Umbenennung
RENAME TABLE existing_table TO old_table, new_table TO existing_table;
Danach musste ich Daten im Umfang von 6 Monaten aus der alten Tabelle in die neue Tabelle übertragen
INSERT INTO existing_table SELECT * FROM old_table WHERE starttime BETWEEN DATE_SUB(NOW(), INTERVAL 6 MONTH) AND NOW();
Vielen Dank, Martin, für den Vorschlag. Ich bin neu bei Serverfault und bin mir daher nicht sicher, wie ich seinen Kommentar als Antwort markieren würde.
Antwort2
MyISAM ist nur für SELECT geeignet. InnoDB hat eine separate READ- und WRITE-Warteschlange. Wenn Sie also 200.000 Zeilen löschen, werden die Tabellen nicht gesperrt. Tabellensperren sind die einzige große Einschränkung von MyISAM, wenn es um die Produktion geht. InnoDB ist für die meisten Anwendungen langsamer als MyISAM, kann aber unter bestimmten Bedingungen aufgrund eines besseren Sperrmechanismus schneller arbeiten; MyISAM sperrt die gesamte Tabelle zum Lesen, während Einfügungen/Aktualisierungen ausgeführt werden. InnoDB kann Sperren auf Zeilenebene durchführen und so mehrere gleichzeitige Schreib- und Lesevorgänge in der Tabelle ermöglichen.
http://kakadba.blogspot.in/2014/02/innodb-vs-myisam.html
Konvertieren von MyISAM in INNODB
Sie können es Tabelle für Tabelle tun
ALTER TABLE table_name ENGINE=InnoDB;
Oder Sie können versuchen, alles mit einem Skript auf einmal zu erledigen
https://stackoverflow.com/questions/3856435/wie-konvertiert-man-alle-tabellen-von-myisam-into-innodb