MyISAM テーブルのサイズを縮小する

MyISAM テーブルのサイズを縮小する

現在約 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

関連情報