Avalados por :

Cómo eliminar filas de precios vencidos de una base de datos de 1,300,000+ modelos de forma eficiente

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

Hola a todos, Tengo un requisito para eliminar todas las filas de precios vencidos de la base de datos utilizando un trabajo cron.
Lo que estoy haciendo actualmente es recuperar la lista de PriceRowModels vencidos y pasarla a la función modelService.removeAll(). El recuento de los modelos es de 1,300,000+. El trabajo se ejecutó durante más de 2 horas y tuvo que ser abortado y el cambio en el recuento fue solo de 4.

es decir, Antes: 1,300,004
Después: 1,300,000

Ahora, seguí consultando mientras el trabajo se estaba ejecutando y el recuento no cambió en absoluto. También he intentado esto reduciendo el recuento total a 83,000+, pero aún así el mismo problema.

¿Alguna idea de por qué está sucediendo esto?

Además, ¿sería mejor iterar la lista de modelos y usar la función remove() para un modelo a la vez?

Gracias.

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

4 Respuestas

0
Cargando...

ModelService.removeAll() básicamente solo llama a ModelService.remove() para cada Modelo en la Lista (o lo hacía la última vez que lo revisé), lo que significa que está disparando una consulta SQL separada por cada elemento. Si la latencia entre tu servidor de aplicaciones y la base de datos es de tan solo 1 ms, eso significa 1 ms EXTRA por elemento a ser eliminado, sin contar los costos adicionales de procesar consultas separadas.

La forma más rápida que he encontrado para hacer esto es creando un script Batch Mode ImpEx que limpiará la tabla de una manera mucho más rápida. Luego puedes ejecutar este ImpEx (usando el modo legacy) desde tu código y los elementos deberían eliminarse de manera razonablemente rápida.

Gracias, James

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

También recurrimos a crear impex en modo por lotes cuando tuvimos que importar 10 millones de pedidos/entradas de pedidos durante la migración, asegúrate de ejecutar el impex en modo por lotes en modo heredado. También puedes configurar el número de hilos a 4, 6 u 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.

Esto es seguro, al mirar la base de datos línea por línea se elimina.

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)
}

Esto es peligroso desde un punto de vista de memoria.

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...

El comportamiento reportado se debió a transacciones: si eliminas datos usando removeAll() , entonces todos los datos se eliminarán en una transacción, y no verás los cambios fuera de la transacción en ejecución. Eso pone mucha presión en la base de datos en caso de transacciones grandes (sugeriría firmemente no afectar más de 10k filas dentro de una transacción). Lo que deberías haber hecho es recuperar un lote de modelos a eliminar, pasarlo a removeAll() , confirmar la transacción y empezar de nuevo. El tamaño del lote a utilizar está entre 100-1000.

Ten en cuenta que los scripts Groovy en HAC se ejecutan en una transacción explícita, por lo tanto, efectivamente no hay diferencia entre remove() y removeAll() . Si estás familiarizado con la API de transacciones en Hybris, no deberías tener problemas para confirmar la transacción actual.

El enfoque de impex podría funcionar porque cada línea se procesa en una transacción separada. Ten en cuenta que la eliminación por lotes a través de impex podría sufrir el mismo problema que el 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?