Everyday Dev System

JPA 쿼리 최적화 본문

내배캠 주요 학습/JPA 심화

JPA 쿼리 최적화

chaeyoung- 2023. 8. 4. 12:33

 

 

1. JPA 가 1차 캐시(영속성 컨텍스트) 를 통해 필요없는 쿼리는 날라가지 않도록 쿼리를 최적화함.

그런데, insert와 delete 쿼리문이 다 날라가는 경우가 있다. 이때 확인해야 할 사항은?

 

1) 해당 함수나 클래스안에 Transaction가 포함되고 있는지 확인

  • @Transactional 으로 함께 감싸져 있어야 최적화 수행.
  • Transactional 없이 Repository 메소드 호출 형태일 경우라면 Repository 내부에서만 @Transactional이 최적화
  • Propagation (전파) 전략 체크해봐야 합니다. 

 

2) 해당 Entity의 ID 식별자 생성 전략을 IDENTITY 로 설정했는지 확인

  • GenerationType.IDENTITY 로 키필드가 설정되어 있으면 DB에 실제로 저장을 해야 유일한 식별자를 구할 수 있으므로 Insert 쿼리가 즉시 DB에 전달됩니다.
  • GenerationType.SEQUENCE 로 설정 추천. DB에 select nextval('thread_seq') 쿼리만 날라감
  • GenerationType.AUTO 로 설정해서 DB에서 선호하는 방식으로 자동 적용 가

 

3) orphanRemova() 영속성 전이에 의해 자식의 삭제잡업이 이루어지는건 아닌지 확인

 

 

 

 

 

2. save()를 수행했는데, Insert 와 Select 쿼리가 날라갔어요!

 

- ID 값이 존재하는 Entity를 save() 하면 업데이트할 필드가 있는지 확인하기 위해 Select 쿼리를 먼저 날려서 조회해옴.

 

	@Transactional
	@Override
	public <S extends T> S save(S entity) {

		Assert.notNull(entity, "Entity must not be null");

		if (entityInformation.isNew(entity)) {
			em.persist(entity);
			return entity;
		} else {
			return em.merge(entity);
		}
	}

 

1) save() 메서드는 해당 파라미터에 들어가는 Entity에 식별자 값이 없을 경우를 새로운 엔티티로 판단해서 persists() 호출

 

2) 식별자 값이 있을 경우에는 이미 있는 Entity로 판단하여 merge() 호출

 

3) merge()를 수행할 때 수정할 필드 여부를 확인하기 위해, Entity의 식별자 값을 통해 DB에 Select를 수행하여 필드 조회

 

4) 조회된 필드들을 Entity와 비교해서 수정된 사항이 있으면 update 쿼리를 수행, 만약 수정 사항이 없으면 아무 query XX.

 

 

 

 

 

Test 클래스에 붙이는 어노테이션은 2개의 목적에 따라 분류한다.

Spring 통합 테스트 & JPA 슬라이스 테스트

 

 

슬라이스 테스트는 다음과 같은 장점이 있기 때문에 더 선호한다.

  • 실제 구동되는 애플리케이션의 설정, 모든 Bean을 로드하기 때문에 시간이 오래 걸리고 무겁다.
  • 테스트 단위가 크기 때문에 디버깅이 어려운 편이다. -> Bean 들이 모두 주입된 상태이므로
  • 웹을 실행시키지 않고 테스트 코드를 통해 빠른 피드백을 받는다는 장점이 희석된다.

 

1. Spring 전체 빈을 사용해야 하는 Spring 통합 테스트

@SpringBootTest
// SpringApplication 띄울때의 Bean들을 모두 생성

@Transactional
// 테스트 메소드들이 모두 한 트랜잭션에 포함되어 최적화 되도록 한다.
// 테스트 대상 함수의 실행환경에서는 Transactional이 안 걸려 있을 수 있으므로 -> 실무 사용시 주의

@Rollback(value=false) 
// 테스트 데이터가 롤백되지 않고 DB에 반영되도록 한다.

 

2. JPA 관련 빈만 사용하는 JPA 슬라이스 테스트

@DataJpaTest
// SpringDataJpa 테스트에 필요한 빈들만 생성

@Transactional
// 테스트 메소드들이 모두 한 트랜잭션에 포함되어 최적화 되도록 한다.
// 테스트 대상 함수의 실행환경에서는 Transactional이 안 걸려 있을 수 있으므로 -> 실무 사용시 주의

@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
// 테스트 용 DB를 따로 설정하지 않고 main 환경 DB를 그대로 사용하도록 합니다.

@Import(JPAConfiguration.class)
// JPAQueryFactory와 같이 테스트시 필요한 빈들을 정의해놓은 Configuration 설정입니다.

@Rollback(value=false) 
// 테스트 데이터가 롤백되지 않고 DB에 반영되도록 한다.

'내배캠 주요 학습 > JPA 심화' 카테고리의 다른 글

@Transaction propagation  (0) 2023.08.04
QueryDSL의 JPAQueryFactory를 활용한 조회문  (0) 2023.08.02
JPA 활용 장점  (0) 2023.08.01
Auditing 활용하기  (1) 2023.08.01
QueryDSL 활용 코드  (0) 2023.08.01