Как стать автором
Обновить

Комментарии 13

Удаление (да и вообще модификация) записей через LIMIT в случае statement-based репликации — не самая хорошая идея. Лучше уж использовать диапазон значений первичного ключа (id >= 5000 AND id < 10000).
Также, в отдельных случаях может быстрее оказаться выбрать оставляемые записи в новую таблицу, на старую сделать truncate, и залить данные обратно. Или просто удалить таблицу, если в нее не ведется запись, а новую переименовать
Ну и конечно, можно таблицы партицировать, в том числе и по времени, и удалять ненужные партиции целиком.
Я когда столкнулся с задачей из статьи, там как раз были сотни миллионов записей и InnoDB, и удаление по времени — сделал партицирование — и это действительно решение, партиция дропается мгновенно. Так что +1 за последний совет.
НЛО прилетело и опубликовало эту надпись здесь
Целостность данных при постоянной записи в базу не пострадает?
НЛО прилетело и опубликовало эту надпись здесь
Так то да, проще всего сделать рядом временную таблицу с нужными данными, а потом подменить ею оригинальную. Но когда в базу постоянно идет запись, а таблицы еще и связаны внешними ключами — проблема удаления больших объемов становится весьма актуальной.
Удаляю с выборкой по полю партиями (id >=1 and id <=5000). И все после того, как один раз решил почистить большой объем и уперся в производительность.
очень странная задача… не могу себе вообще представить ситуацию, когда вообще может потребоваться в таблице на 500М строк удалять больше половины… это явно продакшн, 500М строк — видимо, активно работающий продакшн, удаление большей части таблицы явно связано с изменением логики… ну а если меняется логика, то под новую логику иногда лучше новую архитектуру использовать… на мой взгляд правильное решение в подобной ситуации, это подготовка новой таблицы, вставка в нее тех строк, которые в примере недо было не удалить, а оставить, в этом случае вставлять можно не сразу, а партиями… ну а потом замена одной таблицы на другую… а вообще очень странная задача
Ну, вероятно, необходимо удалить какие-то устаревшие записи (например, за весь период до 01.01.2017). Либо что-то сильно много неожиданно наплодилось и теперь нужно удалить.
Мне как-то в наследство проект достался, где сессии хранились в БД и хранились они по году (или по два, не помню уже). В общем таблица распухла до каких-то феерических значений и было принято решение очистить её, оставив данные за последний месяц.

Тогда-то я радостно по граблям в первый раз и проскакал.
А значения из статьи честно утянуты из этой заметки в ru_root. Она мне живо напомнила мой печальный опыт.
Это может быть таблица логов, в моем случае это было так. Одно время мы копили вообще все действия, собирали их 5 лет. Потом решили что логи храним год, лишнее удалить.

Меня это долгое удаление спасло как-то. Смотрел я на активные процессы в базе, ибо тормозила она, и вдруг вижу там delete * from user. Я думаю, что за глюк, вроде проект работает нормально. Думаю, нет, не может такого запроса быть в продакшн, взял и убил его.


Оказалось, коллега ошибся и не в том окошке очистку тестового запустил. Понятно, что потом установили строгие регламенты, но факт остается фактом. Из-за медленности удаления ужасного исхода удалось избежать. Повезло :)

Самый быстрый способ я нашел такой удаление:
delete from ТАБЛИЦА where seq_num in (select seq_num from ТАБЛИЦА where (УСЛОВИЕ УДАЛЕНИЯ))

База у меня имеет около 500 млн записей и такой командой иногда надо удалять порядка 200-300 тыс записей из нее.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории