Подтвердить что ты не робот

Самый быстрый способ удалить огромную таблицу MySQL

У меня есть огромная база данных MySQL (InnoDB) с миллионами строк в таблице сеансов, которые были созданы несвязанным, неисправным искателем, работающим на том же сервере, что и наш. К сожалению, теперь я должен исправить беспорядок.

Если я пытаюсь truncate table sessions;, кажется, что он занимает слишком много времени (более 30 минут). Меня не интересуют данные; Я просто хочу, чтобы стол был уничтожен как можно быстрее. Есть ли более быстрый способ, или я должен буду просто придерживаться его на ночь?

4b9b3361

Ответ 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;