56

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

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

4

11 に答える 11

148

(これはGoogleの結果で高くなっているので、もう少し説明が便利かもしれないと思いました。)

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

CREATE TABLE new_foo LIKE foo;

RENAME TABLE foo TO old_foo, new_foo TO foo;

DROP TABLE old_foo;

終わり

于 2011-06-14T21:00:51.780 に答える
52

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

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

編集:TRUNCATEは、ドロップまたはDELETEFROMと同じではありません。違いについて混乱している方は、上記のマニュアルリンクを確認してください。TRUNCATEは、可能であれば(FKがない場合)ドロップと同じように機能します。それ以外の場合は、where句のないDELETEFROMのように機能します。

編集:大きなテーブルがあり、MariaDB / MySQLがbinlog_formatをROWとして実行していて、述語/ WHERE句なしでDELETEを実行すると、レプリケーションを維持する、さらにはGaleraを維持するという問題が発生します。フロー制御状態に達することなく実行されているノード。また、バイナリログによってディスクがいっぱいになる可能性があります。気をつけて。

于 2009-05-18T19:28:13.133 に答える
9

MySQLでこれを行うために私が見つけた最良の方法は次のとおりです。

DELETE from table_name LIMIT 1000;

または10,000(発生速度によって異なります)。

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

実際に動作するので、これを試してください。少し時間がかかりますが、動作します。

于 2009-05-19T03:11:28.143 に答える
8

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

于 2009-05-18T19:24:58.163 に答える
3

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

于 2009-05-18T19:25:34.263 に答える
1

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

于 2009-05-18T19:25:05.743 に答える
1

テーブルを完全に削除したいだけの場合は、単にテーブルを削除してみませんか?

于 2009-05-18T19:27:17.177 に答える
1

切り捨ては高速で、通常は数秒以下のオーダーです。30分かかった場合は、切り捨てていたテーブルを参照している外部キーがいくつかある可能性があります。また、ロックの問題が関係している可能性があります。

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

于 2009-05-19T20:28:54.617 に答える
0

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

于 2009-05-19T20:39:11.787 に答える
0

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

于 2009-05-19T02:08:09.457 に答える
0

searleaの答えは素晴らしいですが、コメントに記載されているように、戦闘中に外部キーを失います。 このソリューションも同様です。切り捨ては1秒以内に実行されますが、外部キーは保持されます。

秘訣は、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;
于 2017-03-02T14:26:17.170 に答える