¡Caminando hacia el éxito!

Aprende en Comunidad

Avalados por :

Como remover linhas de preços vencidos de um banco de dados com 1.300.000+ modelos de forma eficiente.

  • Creado 01/03/2024
  • Modificado 01/03/2024
  • 5 Vistas
0
Cargando...

Olá a todos, Tenho um requisito para remover todas as linhas de preços vencidos do banco de dados usando um trabalho cron.
Atualmente, estou recuperando a lista de PriceRowModels vencidos e passando-a para a função modelService.removeAll(). O total de modelos é de 1.300.000+. O trabalho foi executado por mais de 2 horas e teve que ser abortado, com uma alteração no total de apenas 4 modelos.

Ou seja, Antes: 1.300.004
Depois: 1.300.000

Continuei verificando enquanto o trabalho estava sendo executado e o total não mudou de forma alguma. Também tentei reduzir o total para 83.000+, mas o problema persistiu.

Alguma ideia do porquê isso está acontecendo?

Além disso, seria melhor iterar sobre a lista de modelos e usar a função remove() para um modelo de cada vez?

Obrigado.

Pedro Pascal
Se unió el 07/03/2018
Pinterest
Telegram
Linkedin
Whatsapp

4 Respuestas

0
Cargando...

ModelService.removeAll() basicamente só chama ModelService.remove() para cada Modelo na Lista (ou fazia isso da última vez que verifiquei), o que significa que está disparando uma consulta SQL separada para cada elemento. Se a latência entre seu servidor de aplicativos e o banco de dados for de apenas 1 ms, isso significa 1 ms EXTRA por elemento a ser excluído, sem contar os custos adicionais de processar consultas separadas.

A maneira mais rápida que encontrei para fazer isso é criando um script Batch Mode ImpEx que limpará a tabela de forma muito mais rápida. Em seguida, você pode executar este ImpEx (usando o modo legacy) a partir do seu código e os elementos devem ser excluídos de forma razoavelmente rápida.

Obrigado, James

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

Também recorremos à criação de impex em lote quando tivemos que importar 10 milhões de pedidos/entradas de pedidos durante a migração, certifique-se de executar o impex em lote no modo herdado. Também é possível configurar o número de threads para 4, 6 ou 8.

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

Para trabajos de script groovy que necesitan limpiar una gran cantidad de datos, remove es más seguro. Encuentro que removeAll a menudo dará errores de memoria GC y otros.

Isso é seguro, ao examinar o banco de dados linha por linha, é removido.

flexibleSearchService = spring.getBean "flexibleSearchService"


FlexibleSearchQuery taskQuery = new FlexibleSearchQuery("select {pk} from {ProcessTaskLog join BusinessProcess as bp on {bp.pk}={ProcessTaskLog.process} } where  {bp.modifiedTime} < DATE_SUB(NOW(), INTERVAL 1710 DAY) " );

TaskLogs = flexibleSearchService.search(taskQuery).result

TaskLogs.each
{
    modelService.remove(it)
}

Isso é perigoso do ponto de vista da memória.

flexibleSearchService = spring.getBean "flexibleSearchService"


FlexibleSearchQuery taskQuery = new FlexibleSearchQuery("select {pk} from {ProcessTaskLog join BusinessProcess as bp on {bp.pk}={ProcessTaskLog.process} } where  {bp.modifiedTime} < DATE_SUB(NOW(), INTERVAL 1710 DAY) " );

TaskLogs = flexibleSearchService.search(taskQuery).result

modelService.removeAll(TaskLogs)

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019
0
Cargando...

O comportamento relatado ocorreu devido a transações: se você remover dados usando removeAll() , então todos os dados serão excluídos em uma transação, e você não verá as alterações fora da transação em execução. Isso coloca muita pressão no banco de dados em caso de transações grandes (sugeriria fortemente não afetar mais de 10k linhas dentro de uma transação). O que você deveria ter feito é recuperar um lote de modelos a serem excluídos, passá-lo para removeAll() , confirmar a transação e começar de novo. O tamanho do lote a ser utilizado está entre 100-1000.

Note que os scripts Groovy no HAC são executados em uma transação explícita, portanto, efetivamente não há diferença entre remove() e removeAll() . Se você está familiarizado com a API de transações no Hybris, não deveria ter problemas para confirmar a transação atual.

A abordagem impex pode funcionar porque cada linha é processada em uma transação separada. Observe que a exclusão em lotes via impex pode enfrentar o mesmo problema que o script.

Respondido el 15/04/2024
LUCIANO RIOJA GHIOTTO
Se unió el 13/07/2019

contacto@primeinstitute.com

(+51) 1641 9379
(+57) 1489 6964

© 2024 Copyright. Todos los derechos reservados.

Desarrollado por Prime Institute

¡Hola! Soy Diana, asesora académica de Prime Institute, indícame en que curso estas interesado, saludos!
Hola ¿Puedo ayudarte?