現在、約 2,000 万行の MySQL テーブルがあり、それを整理する必要があります。updateTime
(挿入のタイムスタンプ) が 1 か月以上前のすべての行を削除したいと思います。私は個人的にテーブルの順序を変更していないので、データは挿入された順序である必要があり、UNIQUE
2 つのフィールドにキーがありid
、updateTime
. 短時間でこれを行うにはどうすればよいですか?
4 に答える
どのくらいのダウンタイムを許容できますか? 列の大きさは?何個削除していますか?
簡単に言えば、行の削除は、テーブルに対して実行できる最もコストのかかる作業の 1 つです。それは全体的に恐ろしいことです。
それを行う必要がなく、そのためのディスク容量があり、クエリがテーブル サイズの影響を受けない場合 (適切にインデックスが作成されたクエリは通常、テーブル サイズを無視します)、そのままにしておくことができます。
機会があり、テーブルをオフラインにすることができる場合 (そしてテーブルの大部分を削除している場合)、保持する行を新しいテーブルにコピーし、古いテーブルを削除して、名前を変更することをお勧めします。新しいものを古い名前に変更し、インデックスを再作成します。
それ以外の場合は、古き良き削除でほとんど立ち往生しています。
多数の行を削除するには、2 つの方法があります。まず、明白な方法があります:
DELETE FROM table1 WHERE updateTime < NOW() - interval 1 month;
2 番目の (少し複雑な) 方法は、新しいテーブルを作成し、保持したいデータをコピーし、古いテーブルを切り詰めてから、行をコピーして戻すことです。
CREATE TABLE table2 AS
SELECT * FROM table1 WHERE updateTime >= NOW() - interval 1 month;
TRUNCATE table1;
INSERT INTO table1
SELECT * FROM table2;
削除する行数が多く、維持したい行数が比較的少ない場合は、 with句よりも使用TRUNCATE
がはるかに高速です。DELETE
WHERE
制限付きで削除を分割すると、プロセスが高速化される場合があります。
10M 行を削除する必要があり、コマンドを発行しました。何時間も応答しませんでした。
クエリを殺しました(数時間かかりました)
次に、削除を分割します。
DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;
DELETE from table where id > XXXX limit 10000;
次に、このステートメントをファイルに複製し、コマンドを使用しました。
mysql> source /tmp/delete.sql
これははるかに高速でした。
pt-tools などのツールを使用することもできます。および pt アーカイバ。