szybszy insert do bazy

szybszy insert do bazy
MA
  • Rejestracja:około 7 lat
  • Ostatnio:27 dni
  • Postów:100
0

piszę sobie aplikacje w hibernate i mam problem z wydajnością przy insertowaniu do bazy danych.

Kopiuj
for(int a = 0 ; a<persons.size(); a++) {

               Person person = new Person();

                Gender gender = new Gender();

                gender.setName(persons.get(a).getGender());

                gender = genderRepository.save(gender);

                Country country = new Country();

                country.setName(persons.get(a).getCountry());

                country = countryRepository.save(country);

                person.setName(personss.get(a).getFirstName());
                person.setLastName(persons.get(a).getLastName());
                person.setAdditionalInfo(persons.get(a).getIdentifier());
                person.setGender(gender);

                Set<Country> countries = new HashSet();
                countries.add(country);
                person.setCountries(countries);

                personRepository.save(person);

jak poprawić wydajność insertów?

YA
Pokaż konfigurację hibernate'a.
Schadoow
  • Rejestracja:około 13 lat
  • Ostatnio:około 3 godziny
  • Postów:1065
1

Poszukaj pod nazwą bulk insert.

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
3

*Prawdopodobnie *(bo nie wiem tego na pewno).
Tworzenie nowej pełci (Gender) i kraju (Country) dla każdej osoby i wykonywanie na tym save raczej nie pomaga.

Chyba, że wprowadzasz nowatorską ideę: każdy ma własną unikatową płeć i jeden osobisty kraj


jeden i pół terabajta powinno wystarczyć każdemu
Koziołek
z tą pełcią dla każdego to bym uważał.
jarekr000000
@Koziołek: odpada ból z małżeństwami jednopłciowymi. Po prostu nie będzie takich.
Koziołek
I widzisz, problem się rozwiązał.
AK
Opluliście mi monitor. To tutaj się zgłasza, czy w "Hardware" ?
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
1

Po pierwsze włącz logowanie SQLi w konfiguracji Hibernate. To pomaga na wiele problemów wydajnościowych, bo nagle widać jak zły SQL został wygenerowany. W dodatku zło nie wynika z kiepskiej jakości Hibernate, ale z kiepskiej jakości kodu.

Po drugie, to jak pisał @jarekr000000 płcie zazwyczaj kończą się w okolicach 3, krajów mamy około 200. Ty jednak za każdym razem tworzysz nowe. Choć nie sądzę, by było to jakiś poważny problem. Jeden prosty insert czy trzy nie robi większej różnicy bazie danych (serio).

Po trzecie wspomniany bulk load, który będzie zbierał dane i wstawiał je na raz w postaci jednego jebitnego insertu.

Ale ja bym jednak zaczął od tych logów.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
jarekr000000
Strzelam, że z tymi płciami tam nie idzie insert - tylko merge, a w konsekwensji refresh/select za każdym razem (zależy od primary key). Ale nie wiem, jednak nie moja działka.
AK
Płci według Wyroczni Tych Czasów już jest cztery.
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 22 godziny
  • Postów:3277
0

To co pisze @jarekr000000 to prawda, do tego proponowałbym ręcznie sterować otwarciem i zatwierdzeniem transakcji grupując inserty po powiedzmy 100 rekordów. Jeżeli danych jest naprawdę dużo, to pozostaje specyficzny dla konkretnej bazy bulk insert.

MA
  • Rejestracja:około 7 lat
  • Ostatnio:27 dni
  • Postów:100
0

dziękuję za wskazówki, unikalność rekordów w tabeli płeć oraz krajów powinienem zapewnić sobie na poziomie bazy danych czy przy insercie sprawdzić czy dana płeć/kraj już występuje?

piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 22 godziny
  • Postów:3277
0

Na obu poziomach. Z jednej strony baza powinna odrzucać błędne dane (np. zduplikowane wartości) z drugiej strony aplikacja tez nie powinna próbować wstawiać błędnych danych.

TT
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 6 lat
  • Postów:69
0

Abstrahując od samego przyspieszania zapytań - po co w ogóle zapisujesz to na 3 razy?
Gender to pewnie enum, Country to też (chyba?) coś stałego co się dodaje do bazy raz i już zostaje.
Zakładam, że Country=Poland u Kowalskiego, to to samo co Country=Poland u innego Janusza.

Nie wystarczy zrobić

Kopiuj
@Entity
class Person {
    private Long id;
    private Gender gender;
    private List<Country> country;
    ...
}


for (Person p: persons) {
    personRepository.save(person);
}

, a hibernate ogarnie?

MA
tak masz racje, ale wymagania mam takie żeby były 3 tabele (þłeć,osoba,kraj)
TT
Kraj rozumiem jeśli to coś więcej niż enum, płci nie rozumiem w ogóle. Przedyskutował bym te wymagania ;-)
AK
z iloma unikalnymi / powtarzalnymi krajami powiązany jest człowiek? Sugerowałbym Set, jesli już
MA
  • Rejestracja:około 7 lat
  • Ostatnio:27 dni
  • Postów:100
0

poprawiłem sobie tak ten kod i wyglada to juz lepiej, jak teraz zapewnic unikalnosc rekordów?

Kopiuj
@Transactional
    public void  datapersistance(int limit) {
        List<migratedPerson> migratedPersons = repository.findPersons;
        for (migratedPerson personFromList : migratedPersons) {
            Person person = new Person();

            Gender gender = new Gender();
            gender.setName(personFromList.getGender());
            em.persist(gender);

            Country country = new Country();
            country.setName(personFromList.getCountry());
            em.persist(country);

            person.setName(personFromList.getFirstName());
            person.setLastName(personFromList.getLastName());
            person.setAdditionalInfo(personFromList.getIdentifier());
            person.setGender(gender);

            Set<Country> countries = new HashSet();
            countries.add(country);
            person.setCountries(countries);

            em.persist(person);
        }
edytowany 1x, ostatnio: masjav
AK
nie widzę aby ten kod był istotnie lepszy od pierwszej wersji, nic nie skorzystałeś z uwag kolegów. Dalej powołujesz nową płeć itd...
MA
rozwiązanie polega na dodawaniu ifologi, czy jest jakiś mądrzejszy sposób?
AK
tknąłęś się tego projektu, czy Koledzy mają Ci zrobić? Rozumiem masz to zrobić i wykazać się samodzielną pracą? Możliwości są dwie: a) albo encja Gender jest źle zaprojektowana (unikalność) i wyjątku nie ma, ale baza pokazuje czytelnie jakie to chore b) albo jest zaprojektowana dobrze, i nieprawdą jest, że program działa wolno, bo nie działa wcale, rzuca wyjątek.
jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
1

jak poprawić wydajność insertów?

Skonfigurować batch update/insert wg Vlada. Cała paczka musi być w jednej transakcji.


Przeważnie ignoruję niezarejestrowanych użytkowników.
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 22 godziny
  • Postów:3277
1

Tak z ciekawości - co oznacza "problem z wydajnością" konkretnie? Ile tych rekordów wstawiasz do bazy i w jakim czasie?

jarekr000000
To bardzo dobre pytanie.
MA
generalnie chciałbym móc w sensowym czasie wkładać ok 20-50k, chwilowo 100 zajmuję ok 15s, wiec bardzo kiepsko
piotrpo
Jak chcesz wrzucić 50k rekordów w rozsądnym czasie (np. 10 s), to żadne hajbernejty panie, tylko ordynarne połączenie JDBC i żadne transakcje, bulki i inne tylko trzeba takich rzeczy https://www.postgresql.org/docs/9.2/static/sql-copy.html
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

wkładać ok 20-50k, chwilowo 100 zajmuję ok 15s, wiec bardzo kiepsko -

No bez przesady jak jest 100 rekordów na 15 sekund włożone, to na pewno nie jest to wynik problemów wydajnościowych hibernate tylko - albo jego niewłaściwego użycia, albo coś jest BARDZO źle skonfigurowane (baza?, hibernate?). Być może nawet problem jest gdzie indziej w kodzie.

  1. trzeba sprawdzić ile sama baza przetworzy - zrobić tych 100 insertów na boku.
  2. trzeba zobaczyć show_sql.
  3. trzeba zrobić profiling aplikacji, żeby zobaczyć co ona robi

jeden i pół terabajta powinno wystarczyć każdemu
edytowany 5x, ostatnio: jarekr000000
Klaudiusz Wojtkowiak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 3 lata
  • Postów:10
0

W przypadku zapisu do bazy danych, najbardziej obciążająca jest transakcja.

Rozpatrz, czy możesz zapisać w jednym insercie kilkadziesiąt - kilkaset insertów.
Możesz to zrobić pod warunkiem, że możesz trochę opóźnić zapis tych danych w bazce.

Np bez problemu możesz to zrobić w przypadku zapisu logów.

Taki bufor, który zapisujesz w jednej transakcji, powinien mieć obsłużone zamknięcie aplikacji (w predestroyu zapisz zawartość do bazy).
Powinien być obsłużony też procesem cyklicznym (np zapisz bufor co minutę).
Z procesami cyklicznymi uważaj aby niepotrzebnie nie potworzyć wątków - lepiej używać do tego odpowiedniej biblioteki.

Zarówno masowy zapis jak i cykliczne wyzwalanie masz dostępne w bibliotece Daobab, która jest rozrzeszeniem JPA: www.daobab.io


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)