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;