插入数据库花费太多时间

wswtfjt7  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(316)

我创建了一个应用程序,尝试将100条记录插入到我的数据库(mariadb)中,大约需要20秒。如何加快这一行动?
我正在使用hibernate,我的期望是在最多2分钟内插入10公里。

private Person getPerson(ExternalPerson externalPerson) {
        Person person = new Person();

        person.setName(externalPerson.getFirstName());
        person.setLastName(externalPerson.getLastName());
        person.setAdditionalInfo(externalPerson.getIdentifier());
        person.setCountries(Arrays.asList(storeCountryIfNotExist(externalPerson.getCountry())));
        person.setGender(storeGenderIfNotExist(externalPerson.getGender()));

        personRepository.saveAndFlush(person);
        return person;
    }

    private Gender storeGenderIfNotExist(String gender) {
        Gender genderTemp = genderRepository.findByName(gender);
        if (genderTemp != null) {
            return genderRepository.findByName(gender);
        }
        Gender newGender = new Gender();
        newGender.setName(gender);
        return genderRepository.saveAndFlush(newGender);
    }

    private Country storeCountryIfNotExist(String country) {
        Country countrytemp = countryRepository.findByName(country);
        if (countrytemp != null) {
            return countrytemp;
        }
        Country newCountry = new Country();
        newCountry.setName(country);
        return countryRepository.saveAndFlush(newCountry);
    }
w8f9ii69

w8f9ii691#

而不是使用 someRepository.saveAndFlush(someEntity) 使用 someRepository.save(someEntity) 在你插入完所有你可以调用的记录之后 someRepository.flush() . saveAndFlush 方法在每个单独的插入之后立即推送您的更改,这会增加db往返,导致性能降低。
编辑:添加示例代码段。

for ( int i=0; i<10000; i++ ) {
    Person person = new Person(.....);
    session.save(person);

    if ( i % 50 == 0 ) { //50 is the batch size, which can be adjusted to find the sweet spot
        //instead of flushing after every save, flush batch of 50 updates together
        session.flush();
        session.clear();
    }
}
qncylg1j

qncylg1j2#

查看您的代码,我可以看到您正在进行3次插入以创建一个记录。这意味着,首先要使用 storeCountryIfNotExist ,然后使用 storeGenderIfNotExist ,发布这两个,你终于插入 Person 记录。这实际上由3个i/o操作组成,因为您每次都在刷新insert。
为了提高性能,您应该尽量减少i/o操作的数量。首先要做的是在插入3条记录后只刷新一次。我还没有使用mariadb,但是像其他数据库一样,mariadb应该公开一个批插入api,您可以利用它来批量插入10k记录,而不是循环。
希望这有帮助!

相关问题