質問

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

しようとしたら truncate table sessions; 非常に長い時間がかかるようです(30分以上)。データは気にしません。テーブルを一刻も早く消し去りたいのです。もっと手っ取り早い方法はあるのでしょうか、それとも一晩粘るしかないのでしょうか?

役に立ちましたか?

解決

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

あなたが5.0.3よりも大きいMySQLバージョンを使用している場合は、

、これはTRUNCATEで自動的に行われます。あなたはそれがTRUNCATEはFK制約にどのように機能するかを説明し、同様のマニュアルのうち、いくつかの有用な情報を得る可能性があります。 http://dev.mysql.com/doc/refman/5.0 /en/truncate-table.htmlする

EDIT:TRUNCATEからドロップまたはDELETEと同じではありません。違いについて混乱しているものについては、上記のマニュアルのリンクをチェックしてください。 (何のFKのが存在しない場合)それ以外の場合は句ます。

なしでFROM DELETEのように機能し、それができるかのドロップと同じように動作しますTRUNCATE

他のヒント

(これはGoogleの結果に高い上がったように、私はもう少し命令が便利かもしれないと思った。)

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

CREATE TABLE new_foo LIKE foo;

RENAME TABLE foo TO old_foo, new_foo TO foo;

DROP TABLE old_foo;

完了

あなたは、スキーマ、テーブルをドロップして再作成つかむことができませんでした?

私は、MySQLでこれを行うのを発見した最良の方法はあります:

DELETE from table_name LIMIT 1000;

または10,000(それが起こるどのくらいの速に依存します)。

すべての行が削除されるまで、

ループでそれを入れてください。

このことは、実際に動作するよう試みるようにしてください。これは、いくつかの時間がかかるだろうが、それは動作します。

drop tableはそれを取り除くための最速の方法である必要があります。

あなたは「ドロップ」を使用しようとしたことがありますか?私は20ギガバイト以上のテーブルの上にそれを使用しましたし、それは常に秒で完了します。

あなただけの完全テーブルを取り除きたい場合は、なぜ単にをドロップしないのそれ?

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

1がテーブルを空にすることができますが、あなたはそれらのテーブルが同様にスクラブしない限り外部キー参照を削除する必要がありますように、

の切り捨てが効果的に効率的である。

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

私はそれはそう長く取っている理由はわかりません。しかし、おそらく名前変更を試みると、空白のテーブルを再作成します。そして、あなたはそれにかかる時間を気にせず、「余分な」テーブルをドロップすることができます。

サーリーの 答え それは素晴らしいことですが、コメントに記載されているように、戦闘中に外部キーを失います。この解決策も同様です:truncate は 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 Rows は、外部キーとインデックスを持つ他のテーブルに依存していました。

そんな感じ:

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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top