
現在約 5,400 万件のレコードが含まれ、サイズが 20 GB の MyISAM テーブルがあります。このデータベースの設計時に不適切な選択が行われました。私は DB の専門家ではありませんが、このテーブルは継続的に書き込まれ、クエリが頻繁に行われないため、InnoDB の方が適していたと思われます。問題は、このテーブルがほぼ常に書き込み可能である必要があることです。フィールドの 1 つはタイムスタンプ フィールドです。レコードは 5 年前までさかのぼりますが、保持する必要があるのは最後の 6 か月だけです。削除をいくつか試しましたが、200,000 行を削除するのに約 20 分かかり、その間テーブルはロックされ、書き込みできません。数時間ロックされることなく、このテーブルのサイズを縮小する方法について、アドバイスはありますか? 不要な行をより速く削除する方法はありますか? MyISAM テーブルを InnoDB テーブルに変換したことはありません。これは時間のかかるプロセスですか?
答え1
ようやくこのプロジェクトを再検討する時間ができたので、完全を期すために、最終的に何をしたかを投稿したいと思います。DELETE FROMに時間がかかるという元々の問題は、削除する行を指定する方法に関係していると思います。次のようなステートメントを使用していました。
DELETE FROM table WHERE starttime < 20150101 limit 200000;
開始時刻フィールドは実際にはDATETIMEです。私は最終的に、
CREATE TABLE new_table LIKE existing_table;
そして新しいテーブルのエンジンを変更する
ALTER TABLE new_table ENGINE=InnoDB;
そして名前を変更する
RENAME TABLE existing_table TO old_table, new_table TO existing_table;
その後、古いテーブルから6か月分のデータを新しいテーブルに取り込む必要がありました。
INSERT INTO existing_table SELECT * FROM old_table WHERE starttime BETWEEN DATE_SUB(NOW(), INTERVAL 6 MONTH) AND NOW();
提案してくれてありがとう、マーティン。私は serverfault の初心者なので、彼のコメントを回答としてマークする方法がわかりません。
答え2
MyISAM は SELECT にのみ適しています。InnoDB には、READ キューと WRITE キューが別々にあります。そのため、200,000 行を削除する場合、テーブルはロックされません。テーブル ロックは、実稼働時の MyISAM の大きな制限の 1 つです。InnoDB は、ほとんどの用途で MyISAM よりも低速ですが、より優れたロック メカニズムにより、特定の状況ではより高速に実行できます。MyISAM は、挿入/更新の実行中にテーブル全体をロックして読み取ります。InnoDB は行レベルのロックを実行できるため、テーブルで複数の同時書き込みと読み取りが可能です。
http://kakadba.blogspot.in/2014/02/innodb-vs-myisam.html
MyISAM から INNODB への変換
テーブルごとに実行できます
ALTER TABLE table_name ENGINE=InnoDB;
または、スクリプトを使って一度にすべてを実行することもできます
https://stackoverflow.com/questions/3856435/how-to-convert-all-tables-from-myisam-into-innodb