JPA – Improve performance


En estos días tuve una tarea relativamente sencilla que en resumen consistía pasar los datos de una tabla hacia otra, previo algunos procesos de transformación y cambio (esto lo hice invocando código dinámicamente, luego se los comento); así ya se pueden dar una idea de lo que debía hacer, lo que debo destacar aquí es el volumen de datos ya tenía 1450000 filas aproximadamente.

Lo que utilicé para la tarea fue JDK1.8, JPA como base de datos MySQL. Como se pueden imaginar la tarea es bastante sencilla un par de entidades JPA que representan las tablas origen y destino, y lo único que queda es ejecutar las transformaciones. El verdadero problema llegó cuando traté de ejecutar el proceso sobre todo el conjunto de datos. Llegué a procesar 100000 registros en 230 minutos, ese resultado era intolerable.

La tarea se convirtió en mejorar el desempeño de JPA, luego de buscar encontré está página este blog  Java Persistence Performance – How to improve JPA performance by 1,825% y traté de implementar algunas de las recomendaciones que ahí se hacen. En resumen implementé las siguientes (la paginación ya la tenía):

  1. Batch writing, optimización número 8. Agregué las siguientes líneas a mi persistence.xml:
    <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
    <property name="eclipselink.jdbc.batch-writing.size" value="1000" />
  2. Implementé también la optimización 11, agregando las siguientes líneas al mismo archivo
    <property name="eclipselink.persistence-context.flush-mode" value="commit"/>
    <property name="eclipselink.persistence-context.close-on-commit" value="true"/>
    <property name="eclipselink.persistence-context.persist-on-commit" value="false"/>

    No me quise eliminar los mensajes de log.

  3. Finalmente agregué un parámetro al url de mi conexión, quedando así
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://<myserver>:<myport>/<mydatabase>?rewriteBatchedStatements=true"/>

    Esto lo encontré en el mismo blog, pero la entrada Batch Writing, and Dynamic vs Parametrized SQL, how well does your database perform?

Con éstas configuraciones logré procesar el 1450000 registros en 19 minutos, no cambié nada en el código únicamente modifiqué el archivo de configuración de JPA.

Espero que éstas líneas les puedan ayudar a ustedes también.

Deja un comentario