그리고 실제 원인은 무엇인가

Spring Boot 프로젝트를 하다 보면 이런 이야기를 자주 듣습니다.

JPA는 느리다
MyBatis가 더 빠르다
 

하지만 실제로는 JPA 자체가 느린 것이 아니라 잘못 사용하는 경우가 많습니다.

이번 글에서는 JPA가 느리다고 느껴지는 대표적인 이유와 실제 원인을 정리합니다.


1. N+1 문제

JPA 성능 문제의 90%는 N+1 문제입니다.

예를 들어

 
List<Order> orders = orderRepository.findAll();
 

그리고

 
order.getMember().getName();
 

이렇게 접근하면 실행되는 SQL은 다음과 같습니다.

SELECT * FROM orders
SELECT * FROM member WHERE id = 1
SELECT * FROM member WHERE id = 2
SELECT * FROM member WHERE id = 3
 

1 + N
 

쿼리가 실행됩니다.


해결 방법

fetch join 사용

 
@Query("""
SELECT o FROM Order o
JOIN FETCH o.member
""")
 

또는

@EntityGraph
 

사용.


2. Lazy Loading 오해

JPA 기본 전략

ManyToOne → EAGER
OneToMany → LAZY
 

하지만 실무에서는 대부분 이렇게 변경합니다.

모든 관계 → LAZY
 

이유는

불필요한 JOIN 방지
 

입니다.


3. Dirty Checking 비용

JPA는 트랜잭션 종료 시

Dirty Checking
 

을 수행합니다.

엔티티 변경 여부 검사
 

입니다.

대량 데이터 처리 시

10000 entities
 

이면 Dirty Checking 비용이 커집니다.


해결 방법

조회 트랜잭션

 
@Transactional(readOnly = true)
 

4. Persistence Context 메모리 증가

JPA는 조회한 엔티티를 1차 캐시(Persistence Context)에 저장합니다.

 
List<Order> orders = orderRepository.findAll();
 

만약

100000 rows
 

를 조회하면

메모리 증가
 

합니다.


해결 방법

배치 처리 시

flush
clear
 

사용합니다.


5. 불필요한 SELECT

 
orderRepository.save(order);
 

이 경우 JPA는

SELECT
INSERT
 

두 번 실행할 수 있습니다.

이유

merge 동작
 

때문입니다.


6. 잘못된 Fetch 전략

 
@OneToMany(fetch = FetchType.EAGER)
 

이 경우

JOIN 폭발
 

이 발생합니다.

결과

Cartesian Product
 

문제가 발생합니다.


7. JPA를 ORM이 아닌 SQL처럼 사용

JPA는

객체 그래프 관리
 

를 위한 도구입니다.

하지만 이렇게 사용하는 경우가 있습니다.

 
for (Order order : orders) {
orderRepository.save(order);
}
 

결과

1000 UPDATE
 

이 실행됩니다.


실제로 JPA는 느린가?

대부분 경우

JPA = SQL 생성 도구
 

입니다.

JPA가 생성하는 SQL이

좋은 SQL이면 빠르고
나쁜 SQL이면 느립니다.
 

문제는 JPA가 아니라 SQL입니다.
 

JPA가 강력한 이유

JPA는 다음 기능을 제공합니다.

1차 캐시
Dirty Checking
지연 로딩
Entity Graph
JPQL
 

이 기능을 잘 사용하면 SQL보다 더 효율적인 코드가 됩니다.


실무에서 추천 전략

JPA를 사용할 때 다음 규칙을 권장합니다.

모든 관계 → LAZY
조회 쿼리 → fetch join
readOnly 트랜잭션 사용
배치 처리 시 flush / clear
 

정리

JPA 성능 문제는 대부분 다음에서 발생합니다.

N+1 문제
잘못된 Fetch 전략
대량 데이터 조회
 

JPA 자체가 느린 것이 아니라 잘못 사용했을 때 느려집니다.


✔ 핵심 한 줄

JPA는 느린 것이 아니라
SQL을 잘못 생성하면 느려진다.
LIST

+ Recent posts