J'ai une table MyISAM qui contient actuellement environ 54 millions d'enregistrements et dont la taille est de 20 Go. De mauvais choix ont été faits lorsque cette base de données a été conçue. Je ne suis pas un pro des bases de données, mais comme cette table est constamment écrite et rarement interrogée, il semble qu'InnoDB aurait été un meilleur choix. Le problème est que cette table doit être disponible en écriture presque en permanence. L'un des champs est un champ horodaté. Les enregistrements remontent à 5 ans - je n'ai besoin de conserver que les 6 derniers mois. J'ai essayé de procéder à des suppressions, mais il faut environ 20 minutes pour supprimer 200 000 lignes, pendant lesquelles la table est verrouillée et ne peut pas être consultée. Quelqu'un a-t-il des suggestions sur la façon dont je peux réduire la taille de cette table sans qu'elle soit verrouillée pendant plusieurs heures ? Existe-t-il un moyen plus rapide de supprimer les lignes inutiles ? Je n'ai jamais converti une table MyISAM en table InnoDB. Est-ce un processus long ?
Réponses
Trop de publicités?MyISAM est seulement bon pour SELECT. Innodb a des files d'attente READ et WRITE séparées. Ainsi, lorsque vous supprimez 200 000 lignes, les tables ne seront pas verrouillées. Le verrouillage des tables est la principale limitation de MyISAM en production. InnoDB est plus lent que MyISAM pour la plupart des utilisations, mais peut être plus rapide dans certaines conditions en raison d'un meilleur mécanisme de verrouillage ; MyISAM verrouille la table entière pour la lecture pendant l'exécution des insertions/mises à jour. InnoDB peut effectuer un verrouillage au niveau des lignes, ce qui permet de multiples écritures et lectures simultanées sur la table.
http://kakadba.blogspot.in/2014/02/innodb-vs-myisam.html
Conversion de MyISAM en INNODB
Vous pouvez le faire tableau par tableau
ALTER TABLE table_name ENGINE=InnoDB;
Ou vous pouvez essayer script pour tout faire en une fois
https://stackoverflow.com/questions/3856435/how-to-convert-all-tables-from-myisam-into-innodb
J'ai finalement eu le temps de revisiter ce projet et pour être complet, je voulais poster ce que j'ai fini par faire. Le problème initial du DELETE FROM qui prend tant de temps, je crois, est lié à la façon dont je spécifiais les lignes à supprimer. J'utilisais une instruction similaire à
DELETE FROM table WHERE starttime < 20150101 limit 200000;
Le champ "starttime" est en fait une DATETIME. J'ai fini par créer une nouvelle table en utilisant
CREATE TABLE new_table LIKE existing_table;
et ensuite changer le moteur de la nouvelle table
ALTER TABLE new_table ENGINE=InnoDB;
et ensuite renommer
RENAME TABLE existing_table TO old_table, new_table TO existing_table;
Après cela, j'avais besoin d'obtenir 6 mois de données de l'ancienne table dans la nouvelle table.
INSERT INTO existing_table SELECT * FROM old_table WHERE starttime BETWEEN DATE_SUB(NOW(), INTERVAL 6 MONTH) AND NOW();
Merci Martin pour la suggestion. Je suis nouveau sur serverfault donc je ne sais pas comment marquer son commentaire comme une réponse.