szybszy insert do bazy

0

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

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?

1

Poszukaj pod nazwą bulk insert.

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

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.

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.

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?

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.

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ć

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

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

, a hibernate ogarnie?

0

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

@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);
        }
1

jak poprawić wydajność insertów?

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

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