1. ホーム
  2. mysql

[解決済み] MySQLで数百万行を削除する

2023-02-27 13:45:16

質問

最近、私が作業しているサイトでバグを発見し修正したのですが、その結果、テーブル内に何百万もの重複したデータ行が発生しました。これらの重複行は簡単に見つけることができ、1つの削除クエリを実行してすべてを削除することができます。問題は、これだけの行を一度に削除しようとすると、テーブルが長時間ロックされてしまうことです。サイトをダウンさせることなく (テーブルをロックすることで) これらの行を削除するために私が見ることができる唯一の方法は、次のとおりです。

  1. ループ内で何千もの小さな削除クエリを実行するスクリプトを作成します。これは、理論的には、他のクエリがキューに入り、削除の間に実行されるため、ロックされたテーブルの問題を回避することができます。しかし、それでもデータベースの負荷はかなり急上昇し、実行には長い時間がかかります。
  2. テーブルの名前を変更し、既存のテーブルを再作成します (現在は空になります)。その後、名前を変更したテーブルで私のクリーンアップを行います。新しいテーブルの名前を変更し、古いテーブルの名前を戻し、新しい行を名前変更後のテーブルにマージします。この方法は、かなり多くのステップを必要としますが、最小限の中断で仕事を完了させることができます。唯一厄介なのは、問題のテーブルがレポートテーブルであることで、いったん名前を変えて空のテーブルを置くと、元の場所に戻すまで、すべての履歴レポートが消えてしまうのです。さらに、保存されているデータの種類によって、マージ処理に少し手間がかかる可能性があります。全体的には、これが今のところ私の有力な選択肢です。

もしそうなら、サイトをダウンさせることなく、できればユーザーへの影響を最小限に抑えながら、どのように対処されたのでしょうか。2 番の方法、または別の同様の方法を取る場合、深夜に実行し、翌朝早くマージするようにスケジュールを組み、前もってユーザーに知らせることができるので、大きな問題ではありません。私はただ、クリーンアップを行うためのより良い、またはより簡単な方法について誰かがアイデアを持っているかどうかを確認したいだけなのです。

どのように解決するのですか?

DELETE FROM `table`
WHERE (whatever criteria)
ORDER BY `id`
LIMIT 1000

洗って、洗って、影響を受ける行がゼロになるまで繰り返す。 繰り返しの間に1秒か3秒スリープするスクリプトにするとよいでしょう。