Długi czas ładowania obiektów JPA

0

Witam

Zauważyłem, że zawsze przy pobieraniu pierwszej listy List<XXX> muli mi przez 2-3s (sprawdzałem przez System.currentTimeMillis()) . Jest to dość "zaawansowany" obiekt, bo ma w sobie 7 kluczy obcych i każdy klucz obcy ma jeszcze jeden klucz obcy. Myślałem na początku, że jest coś nie tak, ale zauważyłem, że zawsze pierwsze wywołanie listy (obojętnie jakiej) trwa długo. Próbowałem na 2 listach i wygląda to tak :

in = System.currentTimeMillis();
mealDtoDao.findByUser(user);
System.out.println("czas ladowania to = "+(System.currentTimeMillis()-in)); ///27xx -30xx ms
in = System.currentTimeMillis();
mealDtoDao.findAll();
System.out.println("czas ladowania drugi to = "+(System.currentTimeMillis()-in)); ///4x ms

jak zmienię kolejność findAll() z findByUser() to wygląda to tak samo tj. pierwszy 27xx -30xx ms a drugi 4x ms. Jak skrócić ten czas? Bo troszkę jest to kijowo jak wchodzisz do koszyka i musisz poczekac 3 s na załadowanie strony ...

Dodam jeszcze, że w koszyku znajduje się 19 elementów...

1

Czy każde kolejne wywołanie tej akcji (przęładowanie strony?) daje takie same wyniki?
Jeśli tak to chyba coś jest z pulą połączeń słabo.
Ale musisz więcej napisać jak ten system jest skonfigurowany.

0

a co dokładnie mam napisać? Uczę się dopiero i korzystam z spring boot 1.5.2. mysql

1

OK - to dziwne bo nie powinno być problemu. To jest stronka ? Serwis? Czy jak wielokrotnie wywołujesz (np. CTRL-R do zarypania) to te czasy są takie same?

0

Podejrzyj sobie komendy sql, które lecą do serwera i zastanów się, czy tego się spodziewałeś. Są na to 2 sposoby:

  1. Opcja hibernate w persistence.xml, wtedy sql wyląduje w logu, czy na stdout. Można to też osiągnąć zwiększając poziom logowania klasy org.hibernate.SQL.
  2. Opcja mysql, wtedy podglądasz logi mysql.

Prościej w tym przypadku pierwszą opcją. I na dodatek będziesz widział, kiedy system stoi i czeka te 2 sekundy.

Może też być tak, że inicjalizuje się JPA. To może tyle trwać. Załaduj sobie jakiś obiekt z JPA (czyli z bazy danych) przy starcie aplikacji i po sprawie.

0

Powodów dla których pobieranie obiektów z BD trwa długo jest bardzo dużo.

Mówisz, że masz 7 kluczy obcych - a jak definiujesz połączenie? (EAGER czy LAZY czy nie definiujesz nic?)
W Hibernate jest taki problem, że dla każdego takiego klucza domyślnie zostanie wykonane dodatkowe zapytanie do bazy, i zżera to zasoby i wydajność.
To się nazywa chyba problem N+1
jednak dla 19 elementów nie powinno być to tak bardzo zauważalne.

0
jarekczek napisał(a):

Podejrzyj sobie komendy sql, które lecą do serwera i zastanów się, czy tego się spodziewałeś. Są na to 2 sposoby:

  1. Opcja hibernate w persistence.xml, wtedy sql wyląduje w logu, czy na stdout. Można to też osiągnąć zwiększając poziom logowania klasy org.hibernate.SQL.
  2. Opcja mysql, wtedy podglądasz logi mysql.

Prościej w tym przypadku pierwszą opcją. I na dodatek będziesz widział, kiedy system stoi i czeka te 2 sekundy.

Może też być tak, że inicjalizuje się JPA. To może tyle trwać. Załaduj sobie jakiś obiekt z JPA (czyli z bazy danych) przy starcie aplikacji i po sprawie.

zrobiłem tak jak pisałeś i nie ma "przestoju 2-3s" tylko max 100 ms. Jest po prostu bardzo dużo zapytań i trwa to bardzo długo...

Xliwazlimak napisał(a):

Powodów dla których pobieranie obiektów z BD trwa długo jest bardzo dużo.

Mówisz, że masz 7 kluczy obcych - a jak definiujesz połączenie? (EAGER czy LAZY czy nie definiujesz nic?)
W Hibernate jest taki problem, że dla każdego takiego klucza domyślnie zostanie wykonane dodatkowe zapytanie do bazy, i zżera to zasoby i wydajność.
To się nazywa chyba problem N+1
jednak dla 19 elementów nie powinno być to tak bardzo zauważalne.

  1. nie definiuje nic, z tego co wiem to z automatu jest EAGER (popraw mnie o ile się mylę)
  2. 19 elementow ma 261 kluczy obcych...
2

Dla zainteresowanych

Problem leżał po stronie (tak sądzę) git nie wiem jak to możliwe, ale tak wnioskuje.
Zmieniłem branch na poprzedni, żeby sprawdzić czy w poprzednim branchu też tak było. I okazało się, że było ok, więc synchronizowałem branch ze starego do nowego, żeby zacząć od nowa sprawdzam i nadal laguje a oba (branche takie same). Zrobiłem reset hard. Synchronizowalem branch nowy ze starym i nie laguje o_O
...
**
Nie kasowałem jeszcze tego nowego brancha gdzie laguje. Więc jakieś pomysły co mogę sprawdzić co to powoduje piszcie, bo jestem ciekaw !**

1

To wszystko zwyczajnie jest winą tego, że nie umiesz jeszcze mierzyć.

0
jarekr000000 napisał(a):

To wszystko zwyczajnie jest winą tego, że nie umiesz jeszcze mierzyć.

jak nie umiem mierzyć jak widzę bez mierzenia ze stronka ładuje się poniżej 1s a nie 5s jak wcześniej?

0

Oprócz tego przy takich problemach można więcej logować i zobaczyć jakie zapytania lecą do bazy danych.
Jak będziesz mieć to zapytanie to można je wywołać bezpośrednio na bazie danych i zobaczyć ile tam zajmuje.
Trzeba po prostu ustalić które to miejsce powoduje problem po prostu do celu włożyć kij w mrowisko.
Jeżeli baza zwróci szybko odpowiedź to znaczy, że to nie problem z samą konstrukcją modelu i w SQLce tylko w czymś innym.
Nastepnie pula połączeń, transakcje na bazie. Aż wreszcie wykluczysz bazę i przechodzisz do kolejnych rzeczy. I tak w koło macieju aż znajdziesz błąd i będziesz mieć przez 5 minut
chwile zadowolenia. I potem znowu inny BUG i 4 dni walki. I znowu 5 minut zadowolenia. I tak znowu i znowu aż stwierdzisz, że lepiej było zostać rybakiem. Ofc nie musisz zaczynać od bazy. Możesz zacząć od sprawdzenia serwisu, dao i konfiguracji JPA, Hibernate. Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1