Я управляю приложением, которое имеет очень большой (почти 1 ТБ данных с более чем 500 миллионами строк в одной таблице) серверной части базы данных Oracle. База данных на самом деле ничего не делает (ни SProcs, ни триггеры, ни что-либо еще), это просто хранилище данных.
Каждый месяц мы обязаны удалять записи из двух основных таблиц. Критерии очистки различаются и представляют собой комбинацию возраста строки и пары полей состояния. Обычно мы чистим от 10 до 50 миллионов строк в месяц (добавляем около 3-5 миллионов строк в неделю за счет импорта).
В настоящее время мы должны сделать это в пакетах по 50000 строк (т.е. удалить 50000, comit, удалить 50000, зафиксировать, повторить). Попытка удалить весь пакет за один раз приводит к тому, что база данных перестает отвечать на запросы примерно на час (в зависимости от количества строк). Такое удаление строк в пакетах очень сложно для системы, и мы обычно должны делать это «как позволяет время» в течение недели; постоянное выполнение сценария может привести к снижению производительности, что неприемлемо для пользователя.
Я считаю, что этот вид пакетного удаления также снижает производительность индекса и оказывает другие воздействия, которые в конечном итоге приводят к снижению производительности базы данных. В одной таблице 34 индекса, и размер данных индекса фактически больше, чем сами данные.
Вот сценарий, который один из наших ИТ-специалистов использует для этой очистки:
BEGIN
LOOP
delete FROM tbl_raw
where dist_event_date < to_date('[date]','mm/dd/yyyy') and rownum < 50000;
exit when SQL%rowcount < 49999;
commit;
END LOOP;
commit;
END;
Эта база данных должна быть на 99.99999%, и у нас есть только 2-дневный интервал обслуживания один раз в год.
Я ищу лучший способ удаления этих записей, но я еще не нашел ни одного. Какие-либо предложения?