2009-08-03 34 views
8

Estoy usando en mi aplicación una mezcla Spring/Hibernate (nada original). Para una característica dada, tengo que importar el contenido de un archivo CSV en una tabla de mi Oracle DB. Por ahora, juste crear los objetos, hagoInserciones masivas con Spring/Hibernate

HibernateTemplate.saveOrUpdate 

en cada uno de ellos (necesito para recuperar su recién asignado Id)

entonces la transacción se produce al final del método, usando el Spring transaction API.

Todo funciona bien, excepto el rendimiento, lo que es correcto para los objetos de alrededor de 5000, pero no por 100 000 ...

Así que buscar ideas para acelerar estas cosas. He oído hablar de inserciones masivas con Hibernate, pero no pude encontrar ninguna referencia sólida. ¿Alguien puede darme algunas ideas para realizar esta importación con mayor rendimiento?

+1

No es para ser un idiota aquí, pero la documentación sobre esto es bastante concisa y solo toma 5 minutos para leer: http://docs.jboss.org/hibernate/stable/core/reference/en/html /batch.html – Tim

+0

Gracias por el enlace, que es exactamente lo que estaba buscando. Hice algunas investigaciones antes y no lo encontré, pero soy un novato con respecto a la excavación en la documentación de Hibernate. –

Respuesta

7

Algo simple puede probar es para enjuagar y limpiar la sesión decir cada 100 objetos ...

por lo ejecutan

session.flush(); 
session.clear(); 

cada 100 o 1000 inserciones.

Eso limpiará y eliminará la sesión de hibernación y evitará que crezca demasiado (posiblemente por qué los 100 000 objetos tardan tanto).

Además, si utiliza el generador de identificador de identidad, hibernate apagará silenciosamente las inserciones de lote. Las inserciones por lotes mejorarán el rendimiento. También necesitaría especificar la propiedad de configuración hibernate.jdbc.batch_size equivalente a su número de 100 a la vez.

La persistencia de Java de Manning con Hibernate fue la fuente de esto (gran libro: me salvó la piel varias veces).

6

También podría considerar usar StatelessSession ya que está diseñado para operaciones a granel.

StatelessSession ss=sessionFactory().openStatelessSession(); 
Transaction tx=ss.beginTransaction(); 
+1

el enlace es incorrecto: https://www.hibernate.org/hib%5Fdocs/v3/api/org/hibernate/StatelessSession.html –

+0

por ahora, ambos enlaces están equivocados. aquí está el nuevo enlace: http://docs.jboss.org/hibernate/orm/3.3/api/org/hibernate/StatelessSession.html – Isaac

3

A veces, un ORMapper no es el martillo adecuado para la uña. Especialmente las operaciones por lotes a menudo se ejecutan de forma más eficiente utilizando el antiguo JDBC simple. Esto, por supuesto, depende de una variedad de condiciones, pero al menos debería ver esto como una opción y comparar el rendimiento de ambos enfoques.

0

No es simplemente un problema de rendimiento de inserción de base de datos; Si está creando decenas de miles de objetos y no realiza un color, la sesión de Hibernate crecerá hasta que se quede sin memoria.

Cuestiones relacionadas