Wpis z mikrobloga

hej Mirki od #springboot #java, potrzebuję pomocy w optymalizacji tego kodu.

Kod na 1 corowym z 2GB RAM VPSie i bazą w pgsql działa ok 6-10 minut i jest dla mnie nie akceptowalny szczególnie dla takiej ilości danych.
Niestety z zewnętrznego źródła dostaję zawsze komplet UIDów (teraz ok 100 tys.) nieważnych dokumentów bez żadnych dodatkowych znaczników.
Chcę wyfiltrować dokumenty do usunięcia i je usunąć skoro trafiły na czarna listę i zapisać czarną listę dla rozpropagowania dalej identyfikatory dokumentów, które zostały usunięte.
  • 20
@JacobTheLiar: Generalnie tak, choć i tak wszystko zależy od implementacji hashCode i equals. W twoim przypadku nie ma natomiast potrzeby łamania zasad i:
- albo zmapujesz sobie Set do zbióru Uid i w nim będziesz szukał
- albo do contains przekażesz new InvalidDocument(document.getUid())
@63274682374: niestety zmiana tego pogorszyła sprawę i jest teraz 13 minut filtrowania. klasy hashe i equalsy mają. Pobieranie z bazy trwało niecałą sekundę.

return invalidDocuments.contains(new InvalidDocument(document.getUid()));
@JacobTheLiar: a i wd mnie, Twoja metoda isDocumentInvalid jest w porządku. Drugie pytanie jak wygląda ta metoda: removeInvalid.removeInvalidDocuments(toDelete);

Wd mnie powinien iść sql który wygląda tak: delete * from documents d where d.id in (i tutaj id wszystkich documentów do wywalenia). Druga rzecz invalidDocumentRepository.saveAll(toAddInvalidDocuments) powinna być batchem.
a i wd mnie, Twoja metoda isDocumentInvalid jest w porządku.


@saquas: serio?

@JacobTheLiar: > Pobieranie z bazy trwało niecałą sekundę.
Raczej nie. Operacje bazodanowe są tutaj najbardziej czasochłonne. Najprawdopodobniej źle mierzysz czas wykonania, nie bierzesz pod uwagę tego co jest dociągane lazy itp...
Zmiana, którą wprowadziłeś na pewno przyspieszyła samo wyszukiwanie. Jedyne co mogło pogorszyć wydajność to tworzenie nowego obiektu i to tylko jeśłi masz jakiś kod w konstruktorze o
@63274682374: @saquas:

ogólnie każde repository jest springowe/hibernate. podobnie saveall i delete all z JpaRepository.

rozdzieliłem pobieranie i filtrowanie na dwa kroki

List documents = documentList.getAllDocuments();
Set toDelete = documents
.stream()
.filter(document -> isDocumentInvalid(document, invalidDocuments))
.collect(Collectors.toSet());

przed każdym krokiem dałem sdouta i wynik mam taki
step 1 - get 2020-11-02 19:55:42
step 2 - filter 2020-11-02 19:55:43
step - done 2020-11-02 20:08:15

choć kolejne wywołanie wygląda bardziej obiecująco
step 1 -
Dokładnie robi to samo co metoda contains z listy.


@saquas: Dokładnie... tylko, że tu mamy Set!. Wyszukiwanie w nim tak jakby to była lista to o wiele gorsza złożoność. Tym bardziej, że ze sprawdzanych 50k obiektów znajduje kilka/kilknaście obiektów w zbiorze 100k. Oznacza to, że ok 50k razy iterujesz po wszystkich 100k obiektów... a to już strasznie dużo.
@saquas: @63274682374: wszystko ekstra, mimo wszystko dla takiej ilości danych powinno lecieć max kilka sekund przy tej konfiguracji serwera, a nie kilka-kilkanaście minut.
dzięki sugestii @63274682374

Operacje bazodanowe są tutaj najbardziej czasochłonne.


zabrałem się za dokładne analizowanie serwera i to on okazał się winny całemu zamieszaniu (założę osobny wątek, na jego temat). Okazało się, że po ostatnim włamie na mój serwer VPS ktoś coś zostawił co żarło całe zasoby. Pewnie
Pobierz
źródło: comment_16043868198q24jhmz2Q6bBiGfm51VvT.jpg