select문이 여러번 날아가는 문제 때문에 여러가지를 찾아보다가 실험을 하나 해보았다. fetch join 하는 것과 select문 여러개를 날리는 것 중에 무엇이 더 빠를까 라는 의문이 들었기 때문이었다.
그래서 해보았다.
저 두 메서드를 비교해볼 것이다.
비교를 위해 테스트 코드를 작성했다.
@Test
public void AccountTest() {
System.out.println("AccountTest 시작");
em.clear();
Long start1 = System.currentTimeMillis();
Account account = memberRepository.findStudentById("mirror111").get();
DefaultInfoDto dto = new DefaultInfoDto();
dto.setStudentName(account.getStudent().getName());
dto.setSchoolName(account.getStudent().getSchool().getSchoolName());
dto.setClubName(account.getStudent().getClub().getName());
dto.setPositionName(account.getStudent().getPosition().getName());
dto.setStudentType(account.getStudent().getType().name());
System.out.println("dto1: " + dto.toString());
Long end1 = System.currentTimeMillis();
// Assertions.assertThat(account.getId()).isEqualTo("mirror111");
em.flush();
em.clear();
System.out.println("직접 만든 쿼리 실행 시간: " + (end1 - start1));
System.out.println("AccountTest 끝");
}
@Test
public void findStudentInfoByAccountIdTest() {
System.out.println("findStudentInfoByAccountIdTest 시작");
em.clear();
Long start2 = System.currentTimeMillis();
Account account2 = memberRepository.findAccountById("mirror111").get();
DefaultInfoDto dto2 = new DefaultInfoDto();
dto2.setStudentName(account2.getStudent().getName());
dto2.setSchoolName(account2.getStudent().getSchool().getSchoolName());
dto2.setClubName(account2.getStudent().getClub().getName());
dto2.setPositionName(account2.getStudent().getPosition().getName());
dto2.setStudentType(account2.getStudent().getType().name());
System.out.println("dto2: " + dto2.toString());
Long end2 = System.currentTimeMillis();
em.flush();
em.clear();
System.out.println("find 메서드: " + (end2 - start2));
System.out.println("findStudentInfoByAccountIdTest 끝");
}
둘 다 Account 엔티티의 id 값을 가지고 Student 엔티티에 접근해서 School, Club, ClubPosition 엔티티에 추가적으로 접근해 데이터를 반환하는 코드다.
EntityManager.find() 메서드는 조인 없이 연속적으로 select문을 날리는 것을 미리 확인했다.
나는 조인해서 한 번에 가져오는 쪽이 더 빠르지 않을까 하는 예상을 했다.
한 번 결과를 보자.
오히려 select문을 여러개 날리는 EntityManager.find()쪽이 실행 속도가 더 빨랐다.
select문들이 하나의 트랜잭션 안에서 움직여서 그런것일까?
아니면 내가 쿼리를 잘못 짠 것일까 아니면 JPQL을 해석하는데 추가적인 리소스를 잡아먹는 탓일까…
이유를 알기 위해선 더 열심히 공부해야할 것 같다.