插入数据库需要太多时间

时间:2018-08-22 07:21:07

标签: java mysql hibernate spring-boot mariadb

我创建了一个应用程序,尝试将100条记录插入到我的数据库(MariaDB)中,大约需要20秒钟。如何加快此操作的速度?

我正在使用休眠模式,我的期望是在最多2分钟的时间内插入大约10k。

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

2 个答案:

答案 0 :(得分:1)

查看您的代码,我可以看到您正在执行3次插入操作以创建一条记录。这意味着,您首先要使用storeCountryIfNotExist插入国家/地区记录,然后使用storeGenderIfNotExist插入性别记录,然后将这两个记录发布,最后再插入Person记录。每次插入时,这实际上包括3个I / O操作。

为提高性能,您应尽量减少I / O操作的数量。首先要做的是在插入3条记录后只刷新一次。我还没有使用过MariaDB,但像其他任何DB一样,MariaDB应该公开而不是循环,而是公开一个批处理插入API,您可以利用该API批量插入10K记录。

希望这会有所帮助!

答案 1 :(得分:0)

使用someRepository.saveAndFlush(someEntity)代替使用someRepository.save(someEntity),并且在完成所有记录的插入之后,您可以调用someRepository.flush()

saveAndFlush方法可在每次单独插入后立即推送更改,这会增加数据库往返次数,从而降低性能。

编辑:添加示例代码段。

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();
    }
}