Wydajne wyciąganie danych z bazy w Javie

0

Cześć wszystkim.
Chciałbym się zapytać o następującą sprawę, mianowicie: mam w projekt w Javie w którym mam agregat, obiekt hierarchii klas (drzewo) który jest pobierany z bazy danych. Ma on posłużyć jako model do generowania zestawienia do excela. Obecnie agregat jest obłożony adnotacjami JPA i jego używam do pobierania danych jednakże w moim agregacie jest masa joinów do innych tabel i z tego co zauważyłem Hibernate wykonuje więcej niż jednego selecta przez co pobieranie jest strasznie wolne, stąd też moje pytania:

  1. Czy jest opcja aby zmusić hibernate aby pobierał cały agregat jednym zapytaniem? Aby automatu uwzględniał wszystkie joiny bez wykonywania dodatkowych selectów?
  2. Czy istnieją jakieś alternatywne sposoby wyciągania danych z baz danych w Javie, wydajniejsze niż Hibernate? Mam ponad 15 joinów i klepanie "boskiego" sqla mi się nie uśmiecha.
  3. Czy pisanie "boskiego sqla" w przypadku 15tu joinów jest najlepszym rozwiązaniem? Jak sobie radzicie z wyciąganiem danych z bazy które są rozsiane po tabelach? Jakie są najlepsze sposoby?
    3.1 Czy jak się zdecyduje na "boskiego sqla" to czy istnieje jakiś prosty mechanizm do mapowania takiego wyniku na klasy? Po jakiś aliasach, cokolwiek.
0
  1. Tak (wszystkie relacje na eager i @Fetch(FetchMode.JOIN)
  2. Hibernate z samego założenia nie jest wydajny (o czym piszą twórcy, żeby nie używać go do obróbki dużej ilości danych)
  3. Nie ma czegoś takiego jak najlepsze rozwiązanie - opisz szerzej swój przypadek.
    3.1 Nie wiem, chętnie się dowiem :)

Jest jeszcze JOOQ, ale to tylko DSL na SQLa więc i tak będziesz musiał naklepać te joiny tylko że w Javie.

0
pustypawel napisał(a):
  1. Nie ma czegoś takiego jak najlepsze rozwiązanie - opisz szerzej swój przypadek.

Może źle się wysłowiłem: chodzi mi o to jakie rozwiązanie byłoby w takiej sytuacji jednocześnie: czytelne, zrozumiałe, utrzymywane i wydajne?

1
  1. jw, eager
    2,3 problem to masz może z modelem danych w bazie w takim razie? :) Alternatywą jest zrobienie w bazie widoku, który robi te twoje joiny czary-mary a w kodzie aplikacji masz tylko select z tegoż widoku, odcinając się zupełnie od tego jak poryty jest model danych w bazie.
0
Shalom napisał(a):
  1. jw, eager
    2,3 problem to masz może z modelem danych w bazie w takim razie? :) Alternatywą jest zrobienie w bazie widoku, który robi te twoje joiny czary-mary a w kodzie aplikacji masz tylko select z tegoż widoku, odcinając się zupełnie od tego jak poryty jest model danych w bazie.

Na baza danych że tak się wyrażę: musi uciągnąć nowe dane które pierwotnie nie były w planach systemu albo po prostu ja nie łapie toku myślenia moich poprzedników w projekcie. Czyli słowem podsumowania, proponowałbyś napisać "boskiego sqla", opakować go widok w bazie (tam go ukryć) i w aplikacji tylko wołać widok jak tabele w JPA?

3

Tak, chociaż osobiście jestem przeciwnikiem ładowania za dużo do bazy, ale w takim przypadku to nie jest raczej "logika biznesowa", tylko łatanie fuckupu w schemacie bazy. Ale ja bym się zastanowił nad przebudowaniem takiej bazy albo w ogóle nad użyciem czegoś innego. Bo kupą joinów i dziwne rzeczy często suguerują że ktoś np. próbuje zaimplementować noSQLa w SQLu.

0

Ogólnie to "czysty" SQL będzie zawsze mniej wolny niż cokolwiek w Javie. Takie rzeczy łatać można jeszcze po stronie bazy danych (procedury, ewentualnie widok) i mapować gotowe rzeczy do obiektów. Wtedy nie masz narzutu na komunikację, trochę prościej się pisze niż w czystym SQLu bo masz zmienne itp.

0

Duża ilość joinów wcale nie oznacza fuckupa w schemacie danych. Postacie normalne wymuszają większość ilość tabel i nie ma w tym nic złego. Jeśli zapytania robią się zbyt skomplikowane, to tworzysz sobie widoki w bazie danych. Możesz też robić widoki na widokach :) Odpowiednio założone indeksy i nie powinno być problemów z wydajnością. W skrajnych przypadkach można zrobić widok zmaterializowany.

3
wartek01 napisał(a):

Ogólnie to "czysty" SQL będzie zawsze mniej wolny niż cokolwiek w Javie.

W ogólności bezedura czysta java zwykle mocno wygrywa z bazami, choćby przez mniejszy narzut na komunikację.

Edit: ale w sumie to nie jestem pewny czy tego nie miałeś na myśli...

0

Czym jest ten agregat? Reprezentuje pojedyncze coś? Instancję klienta i jego produktów/usług, czy np. Tablicę ogłoszeń ze wszystkimi ogłoszeniami? Pytam, bo piszesz o jakimś zestawieniu, które wydaje mi się jakimś grupowaniem tych Twoich agregatów.

Jeśli masz taki przypadek, że wyciągasz dużo instancji czegoś z bazy (np. przechodzisz po tablicy ogłoszeń) i agregujesz po stronie aplikacji na potrzeby raportu, to może być to słabe rozwiązanie (mieszałbyś wówczas różne aspekty/konteksty - raportowy z jakimś "transakcyjnym" - np. zarządzanie ogłoszeniami i używał tych samych klas do diametralnie różnych rzeczy).
Do raportów moim zdaniem potrzebowałbyś dedykowanego modelu, który mógłby się przekładać na widok bazodanowy. Chyba, że chodzi o coś innego niż raporty z tym "zestawieniem excelowym" :)

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