본문 바로가기

Spring & Java

JPA saveIterable 과 save 저장 속도

반응형


spring 에서 jpa 를 사용하여 save 를 하는것과 save iterable 을 할 경우의 차이점과 속도를 알아보도록 한다.


 List<S> save(Iterable<S> var1)  iterable 형태로 인자 값을 전달 할 경우 hibernate 는 내부적으로 메모리에 올린 다음 한번에 DB 에 커밋을 하도록 한다.


해당 메소드의 내부 로직을 알아보도록 하자.


@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {
List<S> result = new ArrayList();
if(entities == null) {
return result;
} else {
Iterator var3 = entities.iterator();

while(var3.hasNext()) {
S entity = var3.next();
result.add(this.save(entity));
}

return result;
}
}


위에서 본것 과 같이 내부적으로 메모리에 올려서 저장 하도록 되어있다.


아래 코드는 한개씩 저장할때 콜 대는 save 함수이다. 아래와 같이 한개의 객체를 저장할 수있다는것을 알수 있다./

<S extends T> S save(S var1)

내부 로직이 어떻게 구현되었는지 보자


@Transactional
public <S extends T> S save(S entity) {
if(this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}

위에 코드에서 볼수있듯이 한개의 엔티티 객체를 저장하는것을 알수 있다.


아래는 한개씩 저장 하는것과, 리스트 형태로 저장하는 것의 실행시간을 비교해 보았다. 데이터는 10,000 사용함.


@PostConstruct
public void saveUser() throws Exception{

/** jpa saveIterable **/
userRepository.deleteAll();
long startTime = System.currentTimeMillis();
System.out.println("### JPA saveList 함수 시작시간: "+formatTime(startTime));

userRepository.save(generateUserList());
long endTime = System.currentTimeMillis();
System.out.println("### JPA saveList 저장 시간: "+(endTime-startTime)/1000.0);
System.out.println("### JPA saveList 함수 종료 시간: "+formatTime(endTime));

/** jpa save One **/
userRepository.deleteAll();
List<User> userList = generateUserList();
startTime = System.currentTimeMillis();
System.out.println("### JPA saveOne 함수 시작시간: "+formatTime(startTime));
for (User user:userList) {
userRepository.save(user);
}
endTime = System.currentTimeMillis();
System.out.println("### JPA saveOne 저장 시간: "+(endTime-startTime)/1000.0);
System.out.println("### JPA saveOne 함수 종료 시간: "+formatTime(endTime));

}

public List<User> generateUserList(){
List<User> userList = new ArrayList<>();
for (int i = 0; i < 1000 ; i++) {
User user = new User("Testusername-"+i,"Testname-"+i,i);
userList.add(user);
}
return userList;
}

public String formatTime(long time) throws Exception{
Calendar ca = Calendar.getInstance();
ca.setTimeInMillis(time);
return (ca.get(Calendar.HOUR_OF_DAY) + "시 " + ca.get(Calendar.MINUTE) + "분 " + ca.get(Calendar.SECOND) + "." + ca.get(Calendar.MILLISECOND) + "초");
}


실행 결과:


### JPA saveList 함수 시작시간: 143858.621
### JPA saveList 저장 시간: 10.851
### JPA saveList 함수 종료 시간: 14399.472
### JPA saveOne 함수 시작시간: 143914.651
### JPA saveOne 저장 시간: 31.221
### JPA saveOne 함수 종료 시간: 143945.872



실행 결과 3배의 차이가 난다는것을 알수 있다.


또한 jpa 를 사용하여 저장시 select 쿼리를 먼저 한 후 (10000 개의 select를 진행함) insert쿼리가 실행 된다.


반응형

'Spring & Java' 카테고리의 다른 글

spring boot admin server  (0) 2018.02.11
JPA 와 JDBCTemplate 저장 속도 비교  (0) 2017.09.28
JPA 사용시 Lombok 의 Data 어노테이션 사용 이슈  (0) 2017.08.28
xml convert to object  (0) 2017.08.26
Java 8 ArrayList sort  (0) 2017.08.10