ответ Searlea хорош, но, как указано в комментариях, вы теряете внешние ключи во время боя.
это решение аналогично: усечение выполняется за секунду, но вы сохраняете внешние ключи.
Хитрость в том, что мы отключаем / включаем проверки 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;