2012-04-23 14 views
6

Tengo un archivo de texto ~ 6GB que necesito analizar y luego persistir. Al 'analizar' estoy leyendo una línea del archivo (generalmente 2000 caracteres), creo un objeto-coche de la línea y luego lo conservo.problema de rendimiento de hibernación, persiste uno por uno o la masa?

Estoy usando un patrón de consumidor productor para analizar y persistir y me pregunto si hace alguna diferencia (por razones de rendimiento) para persistir un objeto a la vez o 1000 (o cualquier otra cantidad) en una confirmación?

Por el momento, me lleva> 2hr persistir todo (3 millones de líneas) y me parece demasiado tiempo (o puedo estar equivocado).

Actualmente estoy haciendo esto:

public void persistCar(Car car) throws Exception 
{ 
    try 
    { 
     carDAO.beginTransaction(); //get hibernate session... 

     //do all save here. 

     carDAO.commitTransaction(); // commit the session 

    }catch(Exception e) 
    { 
     carDAO.rollback(); 
     e.printStackTrace(); 
    } 
    finally 
    { 
     carDAO.close(); 
    } 
} 

Antes de hacer cualquier cambio de diseño que me preguntaba si hay una razón por la que este diseño es mejor (o no) y si es así, cuáles deben ser los coches. tamaño()? Además, ¿la sesión abierta/cerrada se considera costosa?

public void persistCars(List<Car> cars) throws Exception 
{ 
    try 
    { 
     carDAO.beginTransaction(); //get hibernate session... 
     for (Car car : cars)  
     //do all save here. 

     carDAO.commitTransaction(); // commit the session 

    }catch(Exception e) 
    { 
     carDAO.rollback(); 
     e.printStackTrace(); 
    } 
    finally 
    { 
     carDAO.close(); 
    } 
} 

Respuesta

5

Tradicionalmente hibernación no va tan bien con las inserciones. Hay algunas formas de optimizarlo en algún nivel.

Tome este ejemplo de la API Docs,

Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 

for (int i=0; i<100000; i++) { 
    Customer customer = new Customer(.....); 
    session.save(customer); 
    if (i % 20 == 0) { //20, same as the JDBC batch size 
     //flush a batch of inserts and release memory: 
     session.flush(); 
     session.clear(); 
    } 
} 

tx.commit(); 
session.close(); 

En el ejemplo anterior, si la sesión de vaciado después de la inserción de 20 entradas que harán la operación poco más rápido.

Aquí un interesting article hablando de lo mismo.

Hemos implementado con éxito una forma alternativa de inserciones masivas usando procedimientos almacenados. En este caso, pasará los parámetros al SP como "|" lista separada, y escribirá los scripts de inserción dentro del SP. Aquí el código puede parecer un poco complejo pero es muy efectivo.

+0

Voy a probar este código para el rendimiento y volver a esta respuesta. ¡Gracias! – adhg

+0

por lotes es mejor! – adhg

Cuestiones relacionadas