Optymalizacja requestów w SOAP

0

Cześć, otóż mam pewien problem w pracy: obecnie request w timeoucie (60s) zapisuje do bazy jedynie 1k rekordów, mam osiągnąć 2x/3x to przynajmniej. Zapis jest oczywiście kaskadowy (jeszcze kilka encji obok się zapisuje przy tym requeście). Pytanie: jakie klasyczne próby optymalizacji mogę tutaj podjąć? Chodzi mi głównie o Javowe rozwiązania - pobierać jakoś wcześniej encje, które będą się zapisywały przy tym requeście - tak żeby potem operować na danych już tylko Javowo? Jak to najlepiej rozwiązać? DOdam, że to wszystko stoi na Oraclu + Springu z Apache CXF.

Z góry dzięki za porady.

0
  1. Ale jakie encje? JPA? Wywal.
  2. Zrób batch insert do bazy, najlepiej jakiś duży, więc zamiast insertować po jednym zrób sobie kolejkę która zbiera dane i np. co 60 sekund robi jeden wielki insert. Zamiast 2/3x szybciej będzie pewnie kilkaset/kilka tysięcy razy.
0
  1. Gdybym miał taką moc i mógł wyrzucić JPA to zrobiłbym to - mam niecały miesiąc dośw., więc pozostaje mi jakoś to załatwić jak jest,
  2. Czyli mówisz żeby operacje na danych zrobić sobie wcześniej i zrobić jeden, wielki insert?
0

Generalnie taki bulk insert jest wielokrotnie szybszy niż insertowanie/updatowanie jeden po drugim.

0

W sumie przeszło mi to przez myśl dziś chwilę, bo obecnie jak widziałem to SAVE jest robiony chyba forEach'em po liście, więc dość słabo. Muszę jeszcze sprawdzić czy dane wcześniej wyciągane są jakimś fetch'em czy może też pobierane pojedynczo.

0

DROP DATABASE - klasyczne rozwiązanie.
Wywal bazę danych, a będzie i szybciej i czyściej.

0

:D,
Obawiam się, że takie rozwiązanie mogłoby się skończyć TRUNCATE {moje_imie_nazwisko} w pracy.

0

Zadałbym pytanie skąd się biorą pomysły ładowania dużej liczby danych przez ORMy, ale sam miałem niedawno w robocie przykład jak pewien łoś postanowił tak potraktować pierdyliardy rekordów z danymi pogodowymi (czyli dodatkowo czas miał duże znaczenie), później uparcie twierdził, że baza danych jest do d**y, bo suwak w chmurze się skończył. Po przejściu na load nagle zaczęło działać.

0

No też wolałbym to ładować jakimś SQL'owym bardziej podejściem, ale niestety nie mam za bardzo nic do gadania w tej sprawie, dlatego próbuję zrobić to tak jak mogę przy obecnym stanie.

0

Skoro nie masz nic do gadania, to nic nie zoptymalizujesz.
Jeśli musisz używać JPA, to pozostaje ci trochę podrążyć:
https://www.google.com/search?q=jpa+bulk+load&rlz=1C1GCEA_enPL784PL784&oq=jpa+bulk+load&aqs=chrome..69i57j33.3695j0j0&sourceid=chrome&ie=UTF-8

0

Kurcze to nie jest czarna magia: JProfiler prawde CI powie

0
weiss napisał(a):
  1. Gdybym miał taką moc i mógł wyrzucić JPA to zrobiłbym to - mam niecały miesiąc dośw., więc pozostaje mi jakoś to załatwić jak jest,
  2. Czyli mówisz żeby operacje na danych zrobić sobie wcześniej i zrobić jeden, wielki insert?

ad 1. źle musi być na froncie korporacyjnym, skoro dzieci rzucają do okopów.
ad 2. Jak napisano wyżej bulk insert, ale niepokoi mnie coś innego. 2-3k insertów w ciągu minuty to nie powinien być problem dla Oracle. Nawet jeżeli pod jednym insertem „biznesowym” leży kilka rzeczywistych operacji. Ja bym zaczął od sprawdzenia co tak naprawdę dzieje się z tymi danymi i czy gdzieś po drodze nie dochodzi do jakiś dziwnych spowolnień wynikających z poszukiwania zależności w danych.

Poza tym rzuć okiem na Spring Batch, który potrafi odciążyć główny wątek i umożliwia dość proste zrównoleglenie procesu (o ile to jest możliwe).

0

2-3k insertów w ciągu minuty to nie powinien być problem dla Oracle

Chyba że jednocześnie coś cały czas jeszcze czyta z tejże bazy i izolacja tranzakcji bruździ. No i autor pisze o kaskadowym zapisie więc myśle że to nie jest insert do jednej tabeli, tylko jakiś stop the world z lockiem na całą bazę żeby updatować masę innych tabel.

0

Tak jak poprzednicy napisali, przyczyn może być wiele - zarówno po stronie aplikacji, jak i samej bazy (locki, triggery i inne strzygi). Zanim jednak usuniesz bazę danych, proponuję zwrócić uwagę kolegom, że cel będzie efektywniej osiągnąć stosując JDBC. JPA nie służy do tego, w jakim celu chcesz go użyć. Jeśli nie przejdzie (bo np. konieczność utrzymywania dodatkowego modelu do zapisu, operacje poza kontekstem JPA), spróbuj tego: https://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html - może uda się coś osiągnąć niewielkim nakładem pracy. Niestety trzeba jawnie użyć API Hibernate. Ewentualnie ogarnąć to asynchronicznie z użyciem kolejki - klient nie czeka na zapis. A może w ogóle klient powinien zapylać aplikację za pomocą zdarzeń?

0

Na poczatek zweryfikuj co jest problemem. Ja obstawiam mocne spowolnie na petli i nie czyszczeniu kontektu. Tj czym wiecej obiektow tym wolniej to idzie bo dirty checking nie wyrabia

Kilka miejsc na ktore mozesz popatrzec.

  1. Ustaw sobie batch insert w jdbc na np 20 i co 20 obiektow w tym foreachy czysc kontekst hibernata (mozesz insertowac obiekty tylko jednego typu inaczej hibernate bedzie je momentalnie flushowal)
    1.a) chyba order insert czy cos takiego rozwiazuje ten problem ale to glowy sobie nie dam uciac.
  2. Jesli chcesz je tylko zapisac i nic z nimi nie bedziesz robil to mozesz zamiast zwyklej sesji uzyc statlesssession w hibernate. Wtedy caly dirty checking odpada i nie musisz czyscic kontektu tylko radosnie insertujesz i sobie leci batchem z jdbc co 20.
    2 a) nie wiem czy tutaj nie bedzie problemu jak wyzej z order insert.
  3. Jak masz id wyznaczane sekwencja to podniesc allocation size jak mozesz chodz to nie powinine byc duzy uzysk (podniesc w hibernate i na bazie danych bo sie rozjedzie)

Z rozwian powyzszych plus taki ze nie musisz klepac tych sql recznie tylko sobie wrzucac klasy do zapisu.
Ja po przerobniu po gosciu jego autorskiego rozwiazania jak twoje na statlesssession przyspieszylem to dosc znacznie. Wczesniej 1000 obiektow insertowal sie ponad +5min (xD nie mialem sily wiecej czekac) aktualnie idzie 2tys na sekunde

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