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 10 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 10 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 10 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!
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)