Mejora tus cargas masivas en Ruby On Rails

Mejora tus cargas masivas en Ruby On Rails

Les ha tocado realizar alguna carga masiva de datos? aquí te muestro como hacerla más eficiente con dos ejemplos, una solucion trivial y una mejorada.

solución trivial

El problema de esta solución es la cantidad de veces que vamos a la base de datos (db) y la cantidad de datos que traemos de ella.

Cada vez que ejecutamos model_one = ModelOne.find_by(code: row['code_model_one']), se tienen que realizar al menos estos pasos:

  • Ir a la db y buscar el elemento
  • Traer todos las columnas de esa fila encontrada
  • Reservar memoria e instanciar el objeto en base a la fila encontrada

En resumen, por cada fila estamos haciendo una petición para ir a buscar model_one (select *), luego otra para model_two (select *) y una tercera para guardar model_three (insert).

Si por ejemplo tenemos que cargar 50k de registros, golpearemos 150k de veces a la db y esto es muy costoso.

Vamos a una solución más eficiente

Para elaborar una solución eficiente utilizaremos una gema (activerecord-import) que nos permite realizar insert masivos y además utilizaremos hashes.

Dependiendo si tenemos que iterar:

  • un modelo active_record utilizaria find_in_batches que permite carga por lotes (default batch_size: 1000 que es lo recomendado)
  • un array utilizaria each_slice(1000)

Una solución más eficiente quedaría así:


En resumen:

Si intentamos realizar la carga con esta solución, pasamos de 150k de peticiones a la db a 3*50k/1k, solo 150 peticiones a la db, además disminuimos la cantidad de objetos a instanciar, todo esto impactará positivamente al performance

Conoces alguna otra mejora que podríamos añadir? te leo en los comentarios

Inicia sesión para ver o añadir un comentario.

Otros usuarios han visto

Ver temas