web-dev-qa-db-ja.com

MySQLの大きなテーブルの一括削除

通知テーブルに、Amazon IODSの1000 IOPSのホストである約1億行が含まれており、1か月より古い行を削除したいと思います。

DELETE FROM NOTIFICATION WHERE CreatedAt < DATE_SUB(CURDATE(), INTERVAL 30 day);を実行すると、すべてのIOPSが取得され、プロセスに数時間かかり、「ロック待機タイムアウトが超過しました。トランザクションを再起動してください」という理由で、多くの新しいエントリを挿入できません。

ここで説明する方法を実行しようとしました: http://mysql.rjweb.org/doc.php/deletebig ただし、増分IDの代わりにUUIDを使用しています。

挿入/更新される新しいデータに影響を与えずにこれらの行を削除するための正しい効率的な方法は何ですか?

9
Tianyi Cong

一時テーブルを作成し、切り替えて、過去30日間のデータをコピーします。

#
# Make empty temp table
#
CREATE TABLE NOTIFICATION_NEW LIKE NOTIFICATION;
#
# Switch in new empty temp table
#
RENAME TABLE NOTIFICATION TO NOTIFICATION_OLD,NOTIFICATION_NEW TO NOTIFICATION;
#
# Retrieve last 30 days data 
#
INSERT INTO NOTIFICATION SELECT * FROM NOTIFICATION_OLD
WHERE CreatedAt >= DATE_SUB(CURDATE(), INTERVAL 30 DAY);

営業時間外に、古いテーブルをドロップしてください

DROP TABLE NOTIFICATION_OLD;

このようなDELETEを実行する利点は次のとおりです

  1. NOTIFICATIONは、空のテーブルに切り替えることで高速に空になります。
  2. NOTIFICATIONは新しいINSERTですぐに使用できます
  3. 残りの30日間はNOTIFICATIONに追加され、新しいINSERTを実行できます。
  4. 古いバージョンのNOTIFICATIONを削除しても、新しいINSERTは妨害されません
  5. 注:私は以前にテーブルDELETEのベイトアンドスイッチを実行することをお勧めしました:(2012年7月19日の投稿を参照してください:MySQL MEMORYテーブルでのDELETEクエリの最適化

試してみる !!!

10
RolandoMySQLDBA

私のお気に入りは、Percona Toolkitの pt-archiver です。 MySQLの負荷、レプリケーションラグを処理します。

3
akuzminsky