Удаление огромных порций данных из mysql innodb - PullRequest
5 голосов
/ 12 мая 2010

Мне нужно удалить огромную часть моих данных в производственной базе данных, размер которой составляет около 100 ГБ. Если возможно, я бы хотел минимизировать время простоя.

Мои критерии выбора для удаления, вероятно, будут

УДАЛИТЬ * ОТ ПОСТАВКИ, ГДЕ USER.ID = 5 И UPDATED_AT <100 </p>

Какой лучший способ удалить его?

  • Создать индекс?
  • Написать последовательный скрипт, который удаляет с помощью разбивки на страницы по 1000 строк за раз?

Ответы [ 4 ]

7 голосов
/ 12 мая 2010

Вы можете попробовать использовать метод, упомянутый в mysql doc :

  1. Выберите строки, которые не следует удалять, в пустой таблице, которая имеет ту же структуру, что и исходная таблица:

    ВСТАВИТЬ В t_copy ВЫБРАТЬ * ОТ ГДЕ ...;

  2. Используйте RENAME TABLE для атомарного перемещения оригинальной таблицы и переименования копии в оригинальное имя:

    Переименовать таблицу t в t_old, t_copy TO t;

  3. Оставьте исходный стол:

    DROP TABLE t_old;

2 голосов
/ 12 мая 2010

Если это вообще возможно, используйте двоичное журналирование на уровне строк, а не двоичное журналирование на уровне операторов (это уменьшает количество блокировок), по крайней мере, во время этой операции. Выполните удаление в пакетном режиме (1000 - приличный размер). Используйте первичный ключ в качестве критерия для удаления каждой партии и заказа по первичному ключу (чтобы удалить строки, которые физически близки друг к другу).

1 голос
/ 17 мая 2010

Лучшим способом является постепенное удаление с помощью предложения LIMIT (на 10000 позиций), но не применять порядок. Это позволит MySQL чаще сбрасывать результаты, и переходы не будут огромными. Вы можете легко сделать это с любым установленным вами языком программирования, который имеет разъем для MySQL. Обязательно фиксируйте после каждого утверждения.

Индекс определенно поможет, но его создание займет некоторое время и для таблицы размером 100 ГБ (в любом случае его стоит создать, когда вы собираетесь использовать индекс в будущем). Кстати, ваш текущий запрос неверен, поскольку ссылка на таблицу USER здесь не указана. Вы должны быть осторожны с индексом, чтобы оптимизатор мог извлечь выгоду из его использования.

0 голосов
/ 26 мая 2010

Некоторое время назад я хотел удалить более 99% данных из таблицы. Таблица, которую я удалял, была таблицей сессий, в которой было более 250 миллионов строк, и я хотел получить только самые последние 500 КБ. Самый быстрый способ, которым я придумал, - это выбрать 500 000 строк, которые я хотел, в другую таблицу. Удалите старую таблицу и переименуйте новую таблицу, чтобы заменить удаленную. Это было примерно в 100 раз быстрее, чем при обычном удалении, при котором нужно выбирать записи и перестраивать таблицу.

Это также дает дополнительное преимущество, заключающееся в уменьшении размера файла таблицы, если вы используете InnoDB с innodb_file_per_table = 1, потому что таблицы InnoDB никогда не уменьшаются.

...