인프런 커뮤니티 질문&답변

아리마님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

업데이트 고견 구합니다.

작성

·

1.8K

1

영한님 안녕하세요~ 오늘도 또 하나의 질문을 들고 왔습니다.

예전 MyBatis 방식에서는 보통 수정 처리의 경우, 업데이트 문 한번으로 처리가 가능했는데요.

(내가 수정하고자 하는 일부 항목들만 정의된 Update SQL 문 작성)

JPA 방식에서는 Find 를 먼저 하지 않고 바로 업데이트 하기에는 어려움이 있는 듯 합니다.

예를 들어 Member 객체에 패스워드가 포함되어 있는데 패스워드만 수정을 해야 되는 경우라면

MyBatis 방식에서는 별도의 select 없이 패스워드만 update 를 하면 됐었는데

JPA 에서는 Find 를 통해 객체에 초기셋팅을 한번 한 뒤에 @DynamicUpdate 활용해야

Password 만 변경되는  SQL 을 수행시킬 수가 있는 거 같습니다.

즉, Update 를 위해서는 항상 Select 절이 따라 붙어야 한다는 건데 JPA 장점을 위해 이런 부분은 감수해야 되는 부분이라고

생각해야 되겠죠?? 

답변 1

9

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요 아리마님^^

2가지 포인트가 있네요. 둘다 성능 때문에 사실 고민을 하시는 거구요. 

1. JPA에서 Select 없이 Update만 사용

-> 정말 필요하면 JPA에서 벌크 업데이트를 사용하면 됩니다. (단건도 가능합니다.) 하지만 이런 비즈니스 로직들은 전체 애플리케이션 성능에 주는 영향도가 미비합니다. 암달의 법칙을 생각하면, 이런 부분은 성능 보다는 유지보수성을 고민하는 것이 더 나은 선택이지요. 특히 단순 select 쿼리를 pk로 찍어서 조회하는 것이라면 더더욱 성능에 영향을 주는 것이 미비합니다. 실무에서 정말 고통스러운 상황은 시간이 올래 걸리는 복잡한 쿼리나 순간 많은 write가 일어나는 것 등이지요.

2. JPA에서 변경되는 컬럼만 Update 쿼리 동적으로 사용

-> 흥미롭게도 JPA는 애플리케이션 로딩 시점에 PrepareStatement 스타일로 해당 엔티티의 UPDATE 쿼리를 만들어 둡니다. 그래서 성능만 생각하면 컬럼에 값을 다 넘기는 것이나 하나만 동적으로 만들어서 넘기는 것이나 크게 차이가 나지 않습니다. 상황에 따라 다르겠지만, 오히려 전체 컬럼을 하나의 PrepareStatement 스타일의 SQL을 반복해서 사용하는게, 더 속도가 빠를 수도 있습니다. 물론 컬럼이 너무 많거나, 길이가 너무 길거나, 데이터가 너무 크다면 상황이 달라질 수 있습니다. 하지만 그만큼 크다면 이미 테이블을 분할했겠지요.

여기서 핵심은 이런 단순하게 엔티티 하나를 조회해서 사용하는 핵심 비즈니스 로직들은 전체 애플리케이션 성능에 크게 영향을 주지 않습니다. 대부분 단순 쿼리들이니까요^^ 성능 때문에 우리를 고통스럽게 하는 것은, 잘 인덱스 처리를 해야 하는 복잡한 쿼리들이지요.

결국 유지보수 관점에서 짜잘한 성능은 포기하고, 진짜 중요한 복잡한 조회 성능에 포인트를 맞추는 것이 JPA를 잘 활용하는 방법이라 볼 수 있습니다.

감사합니다^^!

캬 설명 감사합니다 : >