ballqs 님의 블로그
[Spring] JPA Save() vs SaveAll() vs Bulk Insert 본문
DB에 데이터를 저장해야하는 일이 있을때 대용량으로 데이터를 넣어야하는 경우가 있다면 JPA에서는 매번 하나하나 Insert문을 만들어서 실행시키고 있을 것이다. 이건 대용량으로 insert 하는것에 매우 적합하지 않은 방법이다.
SQL에서는 insert 에 values 를 연달아 쓰는 방법이 바로 Bulk Insert 방법이다.
그렇게 글 내용대로 3가지를 비교해보도록 하겠다. 참조글 : Spring JPA Save() vs SaveAll() vs Bulk Insert
Save()
@Test
@Transactional
@Rollback
@DisplayName("Save() 테스트")
void Test1() {
long startTime = System.currentTimeMillis();
for (int i =1; i< 100000; i++){
Schedule schedule = new Schedule();
schedule.setTitle("title title title"+i);
schedule.setContent("content content content"+i+1);
schedule.setWeather("");
User user = new User();
user.setId(1L);
schedule.setUser(user);
scheduleRepository.save(schedule);
}
System.out.println("taken time = "+(System.currentTimeMillis() - startTime)+"ms");
}
save() 메서드를 사용했을때는 26243ms 즉 26s 243ms인 26초 가량이 걸렸습니다.
save() 메서드의 특징은 프록시 기반 동작을 하기 때문에 매번 save()가 호출될 떄 불필요한 프록시 과정이 발생할 수 있다.
SaveAll()
@Test
@Transactional
@Rollback
@DisplayName("SaveAll() 테스트")
void Test1() {
long startTime = System.currentTimeMillis();
List<Schedule> scheduleList = new ArrayList<>();
for (int i =1; i< 100000; i++){
Schedule schedule = new Schedule();
schedule.setTitle("title title title"+i);
schedule.setContent("content content content"+i+1);
schedule.setWeather("");
User user = new User();
user.setId(1L); // 예시로 user_id를 1로 설정
schedule.setUser(user); // Schedule에 User 설정
scheduleList.add(schedule);
}
scheduleRepository.saveAll(scheduleList);
System.out.println("taken time = "+(System.currentTimeMillis() - startTime)+"ms");
}
savaAll()를 사용했을땐 그리 많이 줄진 않았으나 24598ms 즉 24s 598ms.... 24초 정도가 걸렸다. save() 메서드 사용했을때보다 아주 살짝 빨랐다. 뭔 차이인가 싶긴하다... ㅠㅠ
다만 참조글에 인해서는 saveAll이 빠르다고는 하다....
saveAll()은 save()와 다르게 한 번의 트랜잭션을 생성하고, save()를 여러 번 호출하여 같은 인스턴스에서 내부 호출을 하기 때문에 프록시 로직을 타지 않게 되서 빠르다고 한다.
Bulk Insert
Insert에는 단건 삽입이 있고 Bulk 삽입이 있다.
단건 삽입
insert into member (name , email ) values ("이름" , "이메일")
Bulk 삽입
insert into member (name , email )
values
("이름" , "이메일"),
("이름" , "이메일"),
("이름" , "이메일");
하나씩 insert 하는것과 한번에 insert 하는 차이가 존재한다.
save() 와 saveAll() 는 단건 삽입에 해당한다.
코드
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
@Transactional
@Rollback
@DisplayName("Bulk Insert 테스트")
void Test1() {
long startTime = System.currentTimeMillis();
List<Manager> managerList = new ArrayList<>();
for (int i =1; i< 100000; i++){
Manager manager = new Manager();
manager.setManagerNm("이름");
manager.setEmail("이메일");
managerList.add(manager);
}
String sql = "INSERT INTO manager (manager_nm, email)"+
"VALUES (?, ?)";
jdbcTemplate.batchUpdate(sql,
managerList,
managerList.size(),
(PreparedStatement ps, Manager manager) -> {
ps.setString(1, manager.getManagerNm());
ps.setString(2, manager.getEmail());
});
System.out.println("taken time = "+(System.currentTimeMillis() - startTime)+"ms");
}
8786ms 가 걸렸다. 앞에 했던 save() 와 saveAll()에 비해 지나치게 많이 줄은것이 확인이 된다.
앞으로는 대규모 데이터를 삽입해야할 일이 생기면 bulk insert를 사용해야겠다.
'코딩 공부 > Spring' 카테고리의 다른 글
[Spring] AOP (0) | 2024.08.29 |
---|---|
[Spring] Test 코드 작성(stub , mock) (0) | 2024.08.28 |
[Spring] PasswordEncoder 암호화 및 bcrypt 암호화 (0) | 2024.08.23 |
[Spring] Naver Open API 사용방법 (0) | 2024.08.20 |
[Spring] JWT(Json Web Tokens)란? (0) | 2024.08.19 |