web-dev-qa-db-ja.com

巨大なMySQLテーブルを削除する最も簡単な方法

セッションテーブルに数百万行の巨大なMySQL(InnoDB)データベースがあり、それらは私たちと同じサーバーで実行されている無関係で誤動作しているクローラーによって作成されました。残念ながら、私は今混乱を修正しなければなりません。

truncate table sessions;非常に長い時間がかかるようです(30分以上)。データは気にしません。できるだけ早くテーブルを一掃したいだけです。もっと速い方法はありますか、それとも一晩で突き出さなければなりませんか?

52
Kyle Kaitan

最も簡単な方法は、DROP TABLEを使用してテーブルを完全に削除し、同じ定義を使用してテーブルを再作成することです。テーブルに外部キー制約がない場合は、それを行う必要があります。

5.0.3以降のMySQLバージョンを使用している場合、これはTRUNCATEで自動的に行われます。マニュアルからも有用な情報が得られる場合があります。TRKATEがFK制約でどのように機能するかを説明しています。 http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html

編集:TRUNCATEは、ドロップまたはDELETE FROMとは異なります。違いについて混乱している場合は、上記のマニュアルリンクを確認してください。 TRUNCATEは、可能な場合(FKがない場合)ドロップと同じように動作します。そうでない場合、where句のないDELETE FROMのように動作します。

48
womp

(これはGoogleの結果で高くなったので、もう少し指示が役立つと思いました。)

MySQLには、既存のテーブルのような空のテーブルを作成する便利な方法と、アトミックテーブル名変更コマンドがあります。一緒に、これはデータをクリアするための高速な方法です:

CREATE TABLE new_foo LIKE foo;

RENAME TABLE foo TO old_foo, new_foo TO foo;

DROP TABLE old_foo;

完了

128
searlea

MySQLでこれを行う最良の方法は次のとおりです。

DELETE from table_name LIMIT 1000;

または10,000(発生の速さによる)。

すべての行が削除されるまでループに入れます。

実際に機能するため、これを試してください。しばらく時間がかかりますが、機能します。

7
adnan.

スキーマを取得してテーブルを削除し、再作成できませんでしたか?

7
Nate

drop tableは、それを取り除くための最速の方法でなければなりません。

3
Paul Sonier

切り捨ては高速で、通常は数秒以下です。 30分かかった場合、おそらく、切り捨てるテーブルを参照している外部キーのケースがあったでしょう。関係するロックの問題もあります。

Truncateは、テーブルを空にすることができるのと同じくらい効率的ですが、これらのテーブルも同様にスクラブする必要がない限り、外部キー参照を削除する必要がある場合があります。

1
Jeff Ferland

「ドロップ」を使用しようとしましたか? 20GBを超えるテーブルで使用しましたが、常に数秒で完了します。

1
Zenshai

テーブルを完全に削除したい場合は、単にdrop itだけではどうですか?

1
shylent

これらの問題がありました。データベースをRails 2.xとCookieストアでセッションストアとして使用しなくなりました。ただし、テーブルを削除することは適切なソリューションです。一時的にmysqlサービスを停止することを検討してください。ロギングを無効にし、セーフモードで起動してからドロップ/作成を行います。完了したら、再度ロギングをオンにします。

0
Brian Hogan

searleaの answer はニースですが、コメントに記載されているように、戦闘中に外部キーを失います。 この解決策は似ています:切り捨ては1秒以内に実行されますが、外部キーは保持します。

秘Theは、FKチェックを無効/有効にすることです。

SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE NewFoo LIKE Foo;
insert into NewFoo SELECT * from Foo where What_You_Want_To_Keep  

truncate table Foo;
insert into Foo SELECT * from NewFoo;
SET FOREIGN_KEY_CHECKS=1;

拡張回答-一部の行を除くすべてを削除

私の問題は:クレイジーなスクリプトのため、私のテーブルは7.000.000のジャンク行でした。私はこのテーブルのデータの99%を削除する必要がありました、これが削除する前にtmpテーブルに保存したいものをコピーする必要があった理由です.

私が保持する必要があるこれらのFoo行は、外部キーとインデックスを持つ他のテーブルに依存していました。

そんな感じ:

insert into NewFoo SELECT * from Foo where ID in (
 SELECT distinct FooID from TableA 
 union SELECT distinct FooID from TableB 
 union SELECT distinct FooID from TableC
)

しかし、このクエリは常に1時間後にタイムアウトになりました。だから私はこのようにしなければなりませんでした:

CREATE TEMPORARY TABLE tmpFooIDS  ENGINE=MEMORY  AS (SELECT distinct FooID from TableA);
insert into tmpFooIDS SELECT distinct FooID from TableB
insert into tmpFooIDS SELECT distinct FooID from TableC
insert into NewFoo SELECT * from Foo where ID in (select ID from tmpFooIDS);

理論は、インデックスが正しく設定されているため、NewFooを作成する方法はどちらも同じであるはずでしたが、実際にはそうではなかったと思います。

これが、場合によっては次のようにできる理由です。

SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE NewFoo LIKE Foo;

-- Alternative way of keeping some data.
CREATE TEMPORARY TABLE tmpFooIDS  ENGINE=MEMORY  AS (SELECT * from Foo where What_You_Want_To_Keep);
insert into tmpFooIDS SELECT ID from Foo left join Bar where OtherStuff_You_Want_To_Keep_Using_Bar
insert into NewFoo SELECT * from Foo where ID in (select ID from tmpFooIDS);

truncate table Foo;
insert into Foo SELECT * from NewFoo;
SET FOREIGN_KEY_CHECKS=1;
0
Xavier

なぜそんなに時間がかかるのか分かりません。ただし、おそらく名前を変更して、空のテーブルを再作成してください。その後、「余分な」テーブルを、どれだけ時間がかかるか心配することなく削除できます。

0
Brent Baisley