Я использую Spring Boot вместе с Hibernate для создания RESTful API для простого веб-приложения, где я читаю файл .csv и вставляю каждую строку в таблицу базы данных mysql. Я могу успешно сделать это, но это занимает очень много времени для любого большого файла CSV. Я понимаю, что лучше использовать мои операторы вставки для уменьшения количества транзакций, но я не думаю, что это происходит с текущим кодом, который у меня есть. Это то, что я сейчас делаю (работает, но очень медленно):

< Сильный > CsvUploaderController.java

public class CsvUploaderController {

    // CsvUploader Repository definition:
    // @Repository
    // public interface CsvUploaderRepository extends JpaRepository<CityObj, Integer>
    @Autowired
    CsvUploaderRepository csvUploaderRepository;

    // gets called by front end with the .csv file data
    @PutMapping("/upload_csv")
    public List<CityObj> uploadCsv(@RequestBody Object data) {
        // unpackCSV converts an arrayList of Objects to a List of CityObj
        List<CityObj> unpackedCSV = unpackCSV((ArrayList<Object>) data);
        csvUploaderRepository.deleteAll(); // delete all rows in table currently. Not sure if this is relevent to issue

        // save all items as rows in my database
        return csvUploaderRepository.saveAll(unpackedCSV); // this is where it takes forever to complete
    }
    ...
}

< Сильный > application.properties :

spring.datasource.url=jdbc:mysql://url.to.my.database
spring.datasource.username=myusername
spring.datasource.password=weirdpassword
spring.datasource.hikari.maximumPoolSize = 5

spring.jpa.properties.hibernate.generate_statistics=true 
spring.jpa.properties.hibernate.jdbc.batch_size=20 // I've tried playing around with different values. Hasnt helped
#spring.jpa.properties.hibernate.order_inserts=true // I've also tried using this but not sure what it does and didnt help

Что я делаю не так? Как я могу улучшить производительность моих вкладышей? Я правильно понимаю saveAll ()? Моя проблема очень похожа на то, что описано здесь: Spring boot 2 upgrade - весенняя загрузка данных jpa saveAll () очень медленная

0
Isaac Perez 19 Дек 2019 в 01:48

1 ответ

Вы можете добиться некоторой производительности, настроив конфигурацию HikariCP для MySQL: https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration

Поскольку saveAll() внутренне просто повторяет цикл по списку, вы можете выполнить цикл вручную и сбросить каждые 20 объектов, чтобы уменьшить нагрузку на контекст постоянства.

Правильная дозировка, конечно, поможет.

В конце самый быстрый метод будет простым SQL с JdbcTemplate и многозначными INSERT, такими как:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
0
Robert Niestroj 18 Дек 2019 в 23:19