Długi czas ładowania obiektów JPA

Długi czas ładowania obiektów JPA
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
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 :

Kopiuj
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...

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
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.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
0

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

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
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?


jeden i pół terabajta powinno wystarczyć każdemu
jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
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.


Przeważnie ignoruję niezarejestrowanych użytkowników.
edytowany 1x, ostatnio: jarekczek
Xliwazlimak
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:12
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.

zyxist
Nie do końca - nie we wszystkich sytuacjach N+1 jest domyślną opcją. Jeśli używamy metody get(), to Hibernate wie, że np. do relacji wiele-do-jednego lepszy jest JOIN. Inaczej sprawa ma się w HQL-u, gdzie zapytanie nie musi służyć do pobrania dokładnie jednego obiektu i Hibernate nie próbuje tu nic przewidywać. Tutaj N+1 jest najbezpieczniejszą (z punktu widzenia poprawności) domyślną opcją. My natomiast możemy i powinniśmy jawnie określać, jakiej strategii pobierania chcemy użyć. Jednak wskazany przez Ciebie kierunek poszukiwania źródła problemu jest wg mnie właściwy.
jarekr000000
Obstawiam, że tu wcale nie pobieranie z bazy trwa długo. Nie wiadomo co autor mierzy tak naprawdę (normalne).
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
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...
Xliwazlimak
nah, 10 tyś w górę mogło by sprawić problem. Czy tak się dzieje tylko przy pierwszym wywołaniu po włączeniu programu czy przy każdym odświeżeniu strony? Nie wiem jak działa Spring pod spodem, ale może za pierwszym wywołaniem tworzy połączenie z bazą, jakiegoś entitymanagera itd.
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
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 !**

jarekczek
+1 za żart w "winą gita" :)
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

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


jeden i pół terabajta powinno wystarczyć każdemu
TJ
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:35
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?

jarekr000000
myśle, że właśnie dlatego
jarekr000000
poczytaj o jmeter, albo ab, albo siege, albo gatling i użyj któregoś z tych tooli
TJ
nie mam teraz zbyt na to czasu, ale dzięki za info postaram się tego użyć w niedalekiej przyszłości i dam Ci info co wyszło
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
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


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.