Opções que me ocorreram:
Uma grande declaração de exclusão. Por exemplo:
delete from x where (y = 'x' and x = 'y') or (y = 'a' and x = 'b')
Igual ao anterior, mas em pedaços menores, 10k de cada vez?
Crie um procedimento armazenado para que tudo o que estou enviando sejam os dois valores de consulta.
92K de 4M ainda é apenas 2,3% de seus registros. Eu sugeriria sua primeira opção, apenas jogue o que você deseja excluir no banco de dados e deixe o banco de dados resolver (se você der para o banco de dados de uma vez, é provável que ele o faça com mais eficiência do que se você parcelar Fora). A única vez que eu recomendaria fragmentá-lo é se seu aplicativo for crítico em termos de tempo e você estiver preocupado em desacelerá-lo (nesse caso, a outra solução é fazê-lo fora do horário).
Se você estiver tirando 20-30% ou mais dos registros da tabela, recomendo descartar os índices, fazer a exclusão e recriar os índices, seguidos por um
OPTIMIZE TABLE
, mas para 2% dos registros na tabela, a reconstrução do índice sobrecarga não vale a pena (é mais rápido apenas manter os índices atualizados enquanto apaga os registros).Dito isso, depois de fazer a exclusão, correr
OPTIMIZE TABLE
pode não ser uma má ideia - não faça isso durante os horários de pico.Eu sempre usaria
DELETE QUICK
em vez de apenasDELETE
, pois funciona menos com os índices durante a exclusão e, em um estágio posterior, quando você tem a chance de otimizar a tabela, as folhas de índice que foram deixadas para trás são reunidas.Eu certamente recomendo ler a documentação
DELETE QUICK
para ver se isso ajudará.http://dev.mysql.com/doc/refman/5.5/en/delete.html
Você quer ter certeza de que seu plano está procurando encontrar os registros de interesse. Portanto, execute-o bem como um SELECT primeiro com os índices apropriados.
Se o bloqueio envolvido em fazer os DELETEs for uma dor de cabeça, faça-o em lotes. Mas se sua consulta estiver verificando a tabela, o uso de lotes acabará verificando a tabela várias vezes.