Excluindo grandes quantidades (4 milhões de linhas) de dados mysql de maneira eficiente, regularmente

10

Temos uma tabela mysql que a qualquer momento tem cerca de 12 milhões de linhas. Precisamos excluir dados antigos para manter o tamanho da tabela um pouco gerenciável.

No momento, estamos executando esta consulta diariamente, à meia-noite, usando um trabalho cron:

DELETE FROM table WHERE endTime < '1393632001'

A última vez que a consulta foi executada, examinou 4.602.400, levou mais de 3 minutos e a CPU passou pelo telhado.

CPU disparando à meia-noite

O que podemos fazer para impedir que a CPU, as conexões de banco de dados síncronas, a profundidade das sugestões de disco, etc. sejam disparadas de maneira não razoável, enquanto ainda limpam dados antigos?

PS: Você notará que a consulta está realmente acontecendo em um momento bastante inoportuno do nosso ciclo de uso. Suponha que já alteramos o tempo da consulta para ocorrer no ponto mais baixo de uso a cada dia. Além disso, não há índice no "endTime" e eu preferiria mantê-lo dessa maneira, se possível, porque há uma tonelada de dados sendo inseridos com muita regularidade e pouca pesquisa.


fonte
talvez use tarefas cron para excluir a cada 10 minutos e 100k por rodada ou a cada 5 minutos 50k por rodada
pedaços menores em uma base mais regular?
ok, mas parece que isso pode prejudicar nossa experiência do usuário por períodos mais longos :) qualquer coisa que possamos fazer com relação à consulta / design?
11
186k usuários, nenhum db dedicado?
11
Você obterá melhores respostas sobre "Administradores de Banco de Dados"
James Anderson

Respostas:

13

A solução para o seu problema é um recurso do MySQL chamado "particionamento". A documentação está aqui .

O que o particionamento faz é armazenar uma única tabela em "partições" separadas. Eles são definidos por uma expressão específica, geralmente um valor ou intervalo da coluna. No seu caso, isso provavelmente se baseará endTime- assumindo que ele é conhecido quando um registro é criado e não muda.

Você armazenaria o valor de um dia endTimeem cada partição. Em seguida, a etapa de exclusão truncaria uma partição em vez de excluir várias linhas em uma grande tabela. O truncamento da partição seria um método muito mais rápido.

Gordon Linoff
fonte
uau, isso foi incrivelmente útil e parece ser uma solução perfeita. Hora de ler sobre o particionamento! Obrigado!
Embora o particionamento possa ser uma boa solução, tenha cuidado com as despesas gerais - ele pode diminuir significativamente suas consultas. Além de tabela truncada também não é instantânea. Eu consideraria o pt-archiver. Você pode resolver seus problemas com pontas e manter a sua mesa tão simples como é agora
akuzminsky