Gerencio um aplicativo que possui um back-end de banco de dados Oracle muito grande (quase 1 TB de dados com mais de 500 milhões de linhas em uma tabela). O banco de dados realmente não faz nada (sem SProcs, sem gatilhos ou qualquer coisa), é apenas um armazenamento de dados.
Todo mês, somos obrigados a limpar os registros das duas tabelas principais. O critério para a limpeza varia e é uma combinação de idade da linha e alguns campos de status. Normalmente, acabamos limpando entre 10 e 50 milhões de linhas por mês (adicionamos cerca de 3-5 milhões de linhas por semana através de importações).
Atualmente, temos que fazer essa exclusão em lotes de cerca de 50.000 linhas (ou seja, excluir 50000, confirmar, excluir 50000, confirmar, repetir). Tentar excluir o lote inteiro de uma só vez deixa o banco de dados sem resposta por cerca de uma hora (dependendo do número de linhas). A exclusão das linhas em lotes como esse é muito difícil para o sistema e normalmente precisamos fazê-lo "conforme o tempo permitir" ao longo de uma semana; permitir que o script seja executado continuamente pode resultar em uma degradação do desempenho que é inaceitável para o usuário.
Acredito que esse tipo de exclusão de lote também prejudica o desempenho do índice e tem outros impactos que acabam causando a degradação do desempenho do banco de dados. Existem 34 índices em apenas uma tabela e o tamanho dos dados do índice é realmente maior que os próprios dados.
Aqui está o script que um de nossos funcionários de TI usa para fazer essa limpeza:
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;
Esse banco de dados deve estar acima de 99,99999% e só temos uma janela de manutenção de 2 dias uma vez por ano.
Estou procurando um método melhor para remover esses registros, mas ainda não encontrei nenhum. Alguma sugestão?