오늘의하루

JPA deleteByXX의 1+N 문제와 성능 저하 해결 방법 본문

Spring/JPA

JPA deleteByXX의 1+N 문제와 성능 저하 해결 방법

오늘의하루_master 2025. 3. 18. 10:29
반응형

JPA를 사용하면서 deleteByCouponId(Long couponId)와 같은 네이밍 메서드를 활용하면 간편하게 특정 ID를 기반으로 데이터를 삭제할 수 있지만 이러한 메서드를 사용할 때 몇 가지 주의해야 할 점이 있습니다.

deleteByCouponId의 동작 방식

JPA에서 deleteByCouponId와 같은 메서드를 실행하면 내부적으로 다음과 같은 과정을 거칩니다.

  1. 먼저 couponId를 기반으로 해당하는 엔티티 목록을 조회합니다.
  2. 조회된 엔티티들을 하나씩 순회하면서 EntityManager remove 메서드를 호출하여 삭제합니다.
  3. 삭제된 엔티티는 1개씩 flush 되며 트랜잭션이 걸려 있다면 커밋 시 최종 반영됩니다.

이 과정에서 단순히 deleteByCouponId를 호출하면 SQL의 DELETE FROM table WHERE coupon_id = ? 같은 단순한 쿼리가 실행될 것이라고 생각하기 쉽지만 실제로는 조회 후 반복문을 돌면서 삭제하는 방식으로 동작합니다.

deleteBy 메서드 사용 시 발생할 수 있는 문제

1. JPA 내부 코드

// JpaQueryExecution.class
protected Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAccessor accessor) {
    Query query = jpaQuery.createQuery(accessor); // 쿼리 제작 (조회용)
    List<?> resultList = query.getResultList(); // 쿼리 실행

    for(Object o : resultList) { // 반복
        this.em.remove(o); // 실제 삭제 (이때 @Id 삭제)
    }

    return jpaQuery.getQueryMethod().isCollectionQuery() ? resultList : resultList.size();
}

2. 불필요한 조회 비용

만약 deleteByCouponId가 단순히 DELETE FROM 쿼리를 실행하는 것이 아니라면 먼저 해당하는 데이터를 조회하는 쿼리가 실행되기 때문에 데이터 양이 많을 경우 조회하는 비용이 커질 수 있습니다.

3. N+1 문제 발생 가능성

연관된 엔티티가 있는 경우 deleteByCouponId를 호출하면 연관된 엔티티들도 함께 조회될 가능성이 있습니다.

만약 Cascade 설정이 되어 있다면 삭제 시 연관 데이터를 추가적으로 조회하여 삭제하는 과정에서 N+1 문제가 발생할 수 있습니다.

4. 성능 저하 문제

조회된 데이터를 하나씩 삭제하는 방식이므로 데이터 개수가 많다면 불필요한 루프를 반복하는 문제가 발생합니다.

만약 1000개의 데이터를 삭제해야 한다면 단일 DELETE 쿼리 한 번으로 처리할 수 있는 작업을 1000번의 개별 DELETE 쿼리로 실행하게 되어 성능 저하를 유발할 수 있습니다.

해결 방법

@Modifying@Query를 활용한 직접 삭제

조회 없이 바로 삭제하는 방법으로는 @Modifying@Query를 사용하는 것이 있습니다.

@Repository
public interface CouponRepository extends JpaRepository<Coupon, Long> {
    @Modifying
    @Query("DELETE FROM Coupon c WHERE c.couponId = :couponId")
    void deleteByCouponId(@Param("couponId") Long couponId);
}

이렇게 하면 조회 없이 즉시 삭제하는 DELETE FROM 쿼리가 실행되므로 성능이 향상됩니다.

  • 만약 CouponId가 N개라면 IN 절을 활용해서 삭제할 수 있습니다.
 

[JPA] 벌크 연산(Bulk Operation) 알고 계신가요?

1. 벌크 연산 (Bulk Operation)이란?벌크 연산이란 N개의 데이터를 한 번에 UPDATE 또는 DELETE 하는 작업을 의미합니다.Spring Data JPA에서 벌크 연산을 수행하기 위해서는 @Modifying이 필요합니다.2. 왜 필요

jangto.tistory.com

 

반응형
Comments