2012-04-23 13 views
6

Mam plik tekstowy ~ 6GB, który muszę przeanalizować, a później przetrwać. Przez "parsowanie" czytam wiersz z pliku (zwykle 2000 znaków), tworzę obiekt z linii, a później go utrzymuję.Problem z wydajnością hibernacji, jeden po drugim lub masa?

Używam wzorca konsumenckiego producenta do analizowania i utrzymywania i zastanawiam się, czy ma to jakieś znaczenie (ze względu na wydajność) do utrzymywania jednego obiektu na raz lub 1000 (lub jakiejkolwiek innej kwoty) w jednym zatwierdzeniu?

W tej chwili zajmuje mi to> 2 godziny, aby utrzymać wszystko (3 miliony linii) i wydaje mi się, że mam za dużo czasu (a może się myliłem).

Obecnie robię tak:

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

Przed wprowadzeniem jakichkolwiek zmian projektowych Zastanawiałem się, czy istnieje powód, dlaczego ten projekt jest lepiej (lub nie), a jeśli tak, to jakie powinny być samochody. rozmiar()? Czy sesja open/close jest uważana za kosztowną?

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

Odpowiedz

5

Tradycyjnie hibernacja nie pasuje do wkładek luzem. Istnieje kilka sposobów na zoptymalizowanie go do pewnego poziomu.

Weźmy ten przykład z 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(); 

W powyższym przykładzie sesję jeśli spłukuje po włożeniu 20 wpisy, które uczynią pracę trochę szybciej.

Tutaj interesting article omawia te same rzeczy.

Pomyślnie zaimplementowaliśmy alternatywny sposób wprowadzania insertów zbiorczych przy użyciu procedur przechowywanych. W takim przypadku przekażesz parametry do SP jako "|" oddzielona lista i zapisze scrips wstawiania wewnątrz SP. Tutaj kod może wyglądać na nieco skomplikowany, ale jest bardzo skuteczny.

+0

Spróbuję tego kodu pod kątem wydajności i powrócę do tej odpowiedzi. Dzięki! – adhg

+0

porcjowanie jest lepsze! – adhg

Powiązane problemy