Самый быстрый способ удалить огромную таблицу MySQL
У меня есть огромная база данных MySQL (InnoDB) с миллионами строк в таблице сеансов, которые были созданы несвязанным, неисправным искателем, работающим на том же сервере, что и наш. К сожалению, теперь я должен исправить беспорядок.
Если я пытаюсь truncate table sessions;
, кажется, что он занимает слишком много времени (более 30 минут). Меня не интересуют данные; Я просто хочу, чтобы стол был уничтожен как можно быстрее. Есть ли более быстрый способ, или я должен буду просто придерживаться его на ночь?
Ответы
Ответ 1
Самый быстрый способ - использовать DROP TABLE для полного удаления таблицы и воссоздать ее с использованием того же определения. Если у вас нет ограничений внешнего ключа в таблице, вы должны это сделать.
Если вы используете версию MySQL больше 5.0.3, это произойдет автоматически с TRUNCATE. Вы также можете получить полезную информацию из руководства, а также описать, как TRUNCATE работает с ограничениями FK. http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
EDIT: TRUNCATE - это не то же самое, что и drop или DELETE FROM. Для тех, кто смущен различиями, пожалуйста, ознакомьтесь с приведенной выше ссылкой на руководство. TRUNCATE будет действовать так же, как и падение, если это возможно (если нет FK), в противном случае он действует как DELETE FROM без предложения where.
Ответ 2
(Поскольку это оказалось высоким в результатах Google, я думал, что немного больше инструкций может быть удобно.)
MySQL имеет удобный способ создания пустых таблиц, таких как существующие таблицы, и команды переименования атомных таблиц. Вместе это быстрый способ очистки данных:
CREATE TABLE new_foo LIKE foo;
RENAME TABLE foo TO old_foo, new_foo TO foo;
DROP TABLE old_foo;
Готово
Ответ 3
Не могли бы вы захватить схему, чтобы удалить таблицу и воссоздать ее?
Ответ 4
Лучший способ, который я нашел для этого в MySQL, - это:
DELETE from table_name LIMIT 1000;
Или 10 000 (в зависимости от того, как быстро это происходит).
Поместите это в цикл, пока все строки не будут удалены.
Пожалуйста, попробуйте это, так как это действительно сработает. Это займет некоторое время, но оно будет работать.
Ответ 5
drop table
должен быть самым быстрым способом избавиться от него.
Ответ 6
Вы пытались использовать "drop"? Я использовал его на таблицах более 20 ГБ, и он всегда заканчивается через несколько секунд.
Ответ 7
Если вы просто хотите полностью избавиться от таблицы, почему бы не просто удалить его?
Ответ 8
Усечение происходит быстро, обычно на порядок секунд или меньше. Если это заняло 30 минут, у вас, вероятно, был случай с некоторыми внешними ключами, ссылающимися на таблицу, которую вы усекали. Также могут возникать проблемы с блокировкой.
Truncate эффективно эффективен, поскольку можно удалить таблицу, но вам, возможно, придется удалить ссылки на внешние ключи, если вы не хотите, чтобы эти таблицы также были очищены.
Ответ 9
У нас были эти проблемы. Мы больше не используем базу данных в качестве хранилища сеансов с Rails 2.x и хранилищем файлов cookie. Однако падение таблицы - достойное решение. Возможно, вы захотите рассмотреть возможность остановки службы mysql, временно отключить ведение журнала, запустить все в безопасном режиме, а затем сделать снимок/создать. По завершении снова включите ведение журнала.
Ответ 10
Я не уверен, почему это так долго. Но, возможно, попробуйте переименовать и заново создайте пустой стол. Затем вы можете отказаться от "лишней" таблицы, не беспокоясь о том, сколько времени потребуется.
Ответ 11
searlea answer приятно, но, как указано в комментариях, вы теряете внешние ключи во время боя.
это решение похоже: truncate выполняется в течение секунды, но вы сохраняете внешние ключи.
Фокус в том, что мы отключили/активировали проверки 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;
Расширенный ответ - Удалить все, кроме некоторых строк
Моя проблема: из-за сумасшедшего script в моей таблице было 7000 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);
Теория I, потому что индексы настроены правильно, я думаю, что оба способа заполнения 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;