• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

subQuery에서는 fetch를 사용할 수 없을까요?

22.11.11 20:14 작성 조회수 330

1

queryFactory.select(chat.message,
     chat.id,
     ExpressionUtils.as(
           JPAExpressions
               .select(subChat.count())
               .from(subChat)
               .where(subChat.id.eq(chat.id)), "chatCnt"),
             )
            .from(chat)
            .fetch();

위와같이 쿼리를 작성했을 때 채팅방에 서브쿼리를 넣어서 채팅방마다 참여자 수를 구하도록 서브쿼리를 만들었는데

쿼리에서는 서브쿼리에 order by 나 limit 등을 사용해서 조회한 결과 한 건만 서브쿼리로 추가를 할 수 있는데.

querydsl에서는 그렇게 할 수 있는 방법이 있을까요??

예를들어 위의 쿼리문에 ExpressionUtils.~를 추가해서

서브쿼리로 채팅방의 마지막에 작성된 메시지 내용을 같이 가져오고 싶은데 from(chat) 까지는 조회가 잘 되는데(조회가 된다는것은 결과가 이상이 없는건 아닙니다. 결과값이 하나만 나와야 하는데 여러건이 나와서 당연히 문제가 생깁니다.)

서브쿼리에서 limit 제한이나 order by, fetchOne 등을 사용을 할 수가 없는 것 같더라구요..

레퍼런스 사이트에서도 관련된 자료를 찾지 못하고, 구글링을 아무리 해봐도 관련 자료를 찾지 못했는데

 

혹시 위와같은 상황에서는 어떤식으로 처리를 해야할까요??

그동안 제가 했던 방법은

  1. 위의 쿼리로 List로 조회를 한다.

  2. 마지막 메시지를 가져오는 쿼리문을 따로 조회를 한다.

  3. 1번에서 쿼리한 결과를 for문을 돌면서 2번에서 조회된 값을 추가한다.

이런식으로 작업을 했었는데 쿼리를 두 번 실행을 하고, 거기에 반복문을 돌면서 또 값을 추가를 해야하는 상황입니다.

 

일반적으로 이런식으로 사용을 하는지, 아니면 위와같은 경우에는 따로 방법이 있는지 문의드립니다.

내용을 정리하면

  1. 채팅방, 채팅유저, 채팅메시지의 3개 테이블이 있습니다.

  2. 1row에는 채팅방 아이디, 채팅유저정보, 해당 채팅방 아이디에서 작성된 마지막 메시지 내용

  3. 2번의 정보를 1row에 출력을 하고 싶은데 쿼리를 두 번 돌려서 for문으로 해당 값들을 추가했습니다.

  4. 3번 방식 말고 다른 방식으로(서브쿼리등) 해결할 수 있는 방법이 있을까요?

 

 

 

답변 1

답변을 작성해보세요.

1

안녕하세요. 아버지님

저도 정확한 답을 잘 모르겠습니다.

이렇게 복잡해지는 경우에는 JdbcTemplate이나 네이티브 쿼리를 사용하는 것을 권장드립니다.

관련해서 혹시 아시는 분께서는 답변 남겨주시길 부탁드려요.

감사합니다.

답변 감사합니다.

제가 적용했던 방법은 왼만하면 querydsl만을 사용할려고 하다보니

  1. 채팅방 목록 데이터를 querydsl로 조회를 한 후에

  2. 1번에서 쿼리한 수 만큼 반복문을 돌리면서 해당 방의 마지막 메시지를 가져와서 Projections.bean을 통해서 값을 넣는식으로 만들었습니다.

 

혹시 이 방법하고, 네이티브 쿼리를 사용하는 방법하고 둘 중 어느것이 더 나은 방법일까요??

데이터가 많아지면 위와같이 목록쿼리를 실행하고, 그 수 만큼 반복해서 쿼리를 조회해서 값을 넣는 방법이 네이티브 쿼리를 작성하는 것 보다 부담이 더 많아질 것이라고 생각이 됩니다.

하지만 네이티브 쿼리에서도 join 을 사용하면 부담이 있을 것 같습니다.

실무에서는 조인을 많이 사용하는지, 아니면 제가 사용했던 방법도 성능상이나 기타 문제가 없는지 궁금합니다.

대부분 조인등을 사용해서 한 번에 모두 조회를 하는 식으로 하는것이 일반적인 방법인 것 같았는데

querydsl을 사용하는 가장 큰 장점이 네이티브 쿼리의 사용을 최소한으로 줄이면서 오타를 쉽게 찾을 수 있는 장점이 있는데, 네이티브 쿼리와 함께 사용을 하게 된다면 이러한 장점이 많이 줄어들 수 밖에 없을 것 같은데..

통계나 복잡한 쿼리에서는 네이티브 쿼리를 어쩔 수 없이 사용을 할 수 밖에 없는 상황이 실무에서는 다반사라고 생각을 합니다.

그럴경우 실무에서는 어떤식으로 문제를 해결하는지 궁금합니다.

안녕하세요. 아버지님

복잡한 통계 쿼리의 경우 네이티브 쿼리를 사용하는 것이 더 효과적인 경우가 많습니다.

하이버네이트를 만든 게빈킹도 90% 정도의 문제를 해결하는 것을 목표로 만들었습니다.

결과적으로 실무에서는 적절하게 둘을 섞어서 사용하는 것이 좋습니다.

성능 관련해서는 성능이 정말 중요한 부분에는 네이티브 쿼리를 통해 최적화가 가능하다면 고려하고, 그렇지 않은 경우에는 쿼리가 조금 더 사용되어도 JPA를 사용하는 것이 코드상 더 효율적인 경우들이 많습니다.

결국 상황에 따라서 다른데, 정리해 드리자면 성능이 크게 중요하지 않은 상황이라면 코드 효율화를 더 중요하게 생각하고, 성능이 중요한 일부 부분들은 성능 최적화에 더 에너지를 들여야 합니다.

그리고 통계 쿼리나 아주 복잡한 쿼리는 네이티브 쿼리를 처음부터 고려하는 것이 좋습니다.

감사합니다.

답변 감사합니다.

말씀하신대로 성능/효율화를 고민해 보면서 선택을 하는게 가장 좋을 것 같네요.