• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

쿼리 최적화 관련 (직접 쿼리날리기, 엔티티를 통한 접근)

23.04.19 19:40 작성 조회수 425

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
여기에 질문 내용을 남겨주세요.

특정 엔티티에 접근을 하려고 할 때 1)직접 쿼리를 통해 접근 하는 방법, 2) 엔티티와 자바 메소드를 통해 접근하는 방법 중 어떤 것을 선택해야할까요?

예를 들어 User엔티티와 Follow엔티티가 1대N으로 설정되어있다고 가정한다면.

user.getFollows()를 한다면 Select 쿼리가 한 번 더 나가게됩니다. 이것도 user를 repository에서 가져올때 follows를 join fetch 해온다면 괜찮지만

insert또는 delete할 때가 고민입니다

Insert일 때

1) cascade타입을 persist또는 all로 설정해둔다면

user.getFollows.add(follow) 쿼리로 할 수 있습니다

하지만 이렇다면 Select문, Insert문 쿼리가 두번이 추가가 됩니다

2)하지만 followRepository.save(follow)를 한다면 insert문 한 번의 쿼리만 나가게 됩니다.

delete일 떄

1)

user.getFollows.delete(follow)

또한 Select문, delete문 두번의 쿼리가 나가지만

2)followRepository.delete(follow)는 한 번의 쿼리가 나갑니다. 하지만 이마저도

이전에 follow를 검색하는 과정에서 쿼리가 더 나갈 수 있습니다

ex)

User user = userRepository.findByUserId(userId);

Follow follow = user.get~~; // 삭제할 follow를 구별해내는 메소드

user.getFollows.delete(follow)

-> 쿼리가 총 4번이 나갈 수 있습니다

하지만 이걸 followRepository에서

@Query("delete ~~");

void deleteByUserId(@Param("userId"))

이 메소드를 한 번 실행시키는 걸로 축소한다면 단 한 번의 쿼리로 축소할 수 있습니다.

이렇다면 웬만한 데이터에 접근할 때 직접 쿼리를 날리는게 좋지 않나요? 왜 엔티티상으로 데이터에 접근하는지 궁금합니다.

그리고 만약에 특유의 이유가 있다고 하여도 (객체 지향의 이유 등등) 쿼리를 4번에서 1번으로 줄일 수 있는 것을 포기할 정도의 이유인지도 궁금합니다!

 

답변 1

답변을 작성해보세요.

4

안녕하세요. hong19kings님

각각의 방식은 나름의 트레이드 오프가 있습니다.

말씀하신 직접 쿼리를 사용하는 것과 엔티티와 자바 메소드를 통해 접근하는 방법 사이에서 선택해야 할 때, 어떤 방식이 더 나은지는 상황과 요구 사항에 따라 다릅니다. 각 방법의 장단점을 고려하여 결정해야 합니다.

엔티티와 자바 메소드를 사용하는 방법의 장점:

  1. 코드의 가독성이 좋습니다. 객체 지향적인 방식으로 접근하기 때문에 코드를 이해하기 쉽습니다.

  2. 코드의 유지 보수가 쉽습니다. 엔티티와 메소드를 사용하면 데이터베이스 스키마가 변경되더라도 코드를 쉽게 수정할 수 있습니다.

  3. 객체 지향 프로그래밍의 장점을 활용할 수 있습니다. 캡슐화, 상속 등 객체 지향 프로그래밍의 특징을 활용하여 효율적인 코드를 작성할 수 있습니다.

직접 쿼리를 사용하는 방법의 장점:

  1. 성능 최적화에 유리합니다. 필요한 데이터만 조회하거나 쿼리를 최적화할 수 있습니다.

  2. 복잡한 조건이나 연산을 처리하기 쉽습니다. SQL 쿼리를 직접 작성하기 때문에 데이터베이스에서 처리할 수 있는 복잡한 로직을 쉽게 구현할 수 있습니다.

즉, 객체 지향적인 방식을 선호하고 코드의 가독성과 유지 보수성을 중요하게 생각한다면 엔티티와 메소드를 사용하는 방식이 좋습니다. 반면에 성능 최적화와 복잡한 쿼리 처리가 중요하다면 직접 쿼리를 사용하는 방식이 더 적합할 수 있습니다.

예시로 설명을 드리자면

User엔티티와 Follow엔티티가 1대N으로 설정되어있다고 있다고 가정한다면 user.getFollows()를 통해서 프록시를 초기화 하게 되면 쿼리가 한번 더 호출되겠지요. 그런데 만약에 주로 사용하는 메서드에서는 user만 조회하고, user.getFollows()는 특정 메서드에서 아주 가끔 호출된다면 어떨까요?

이런 경우에는 항상 fetch join을 사용해서 데이터를 한번에 많이 조회하는 것이 성능에 더 좋지 않은 영향을 주겠지요?

그리고 또 한가지 암달의 법칙이라는 것이 있습니다.

애플리케이션 전체를 보면 사실 PK를 기준으로 데이터를 단순히 조회하는 것은 성능에 미치는 영향이 매우 미미합니다. 대부분의 SQL 쿼리 성능 문제는 복잡한 리스트나 통계 데이터 등을 조회할 때 발생합니다.

제가 가장 추천하는 방법 다음과 같습니다.

  1. 성능 보다는 유지보수 하기 좋은 코드를 작성한다.

  2. 성능 테스트를 진행하면서 최적화가 꼭 필요한 부분을 발견하면 최적화하는 코드를 작성한다.

도움이 되셨길 바래요. 감사합니다.

변우용님의 프로필

변우용

2023.05.22

너무 친절합니다! 감사합니다