devwithpug / devwithpug.github.io

https://devwithpug.github.io
MIT License
1 stars 1 forks source link

java/querydsl-with-datajpa/ #6

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

Querydsl으로 안전한 쿼리 작성하기 + DataJPA 공부하며 끄적이는 장소 🐶

개요

https://devwithpug.github.io/java/querydsl-with-datajpa/

doyoung0205 commented 2 years ago

안녕하세요. 작성해주신 글 잘 읽었습니다.

문의사항이 있어서 댓글을 남깁니다.

  1. PageImpl 예제 중에서 findUserWithPaging 메소드 에 관한 것 입니다.

content.size() 매개변수에 넣는 것이 아니라

long total = queryFactory
            .selectFrom(user)
            .where(user.username.like("user_"))
            .fetch()
                         .size();

위의 선언된 total 값을 넣어줘야 하지 않을까 싶습니다.


  1. List 에서 size 값을 구하는데 필요한 시간복잡도는 O(1) 로 알고 있습니다. fetch() 의 결과 타입은 ArrayList 이며 ArrayList 의 size 메서드를 보면 아래와 같이 구현되어있기 때문입니다.
    public int size() {
        return size;
    }

List.size 가 O(n) 인 이유를 알 수 있을까요?

devwithpug commented 2 years ago

@doyoung0205 안녕하세요.

남겨주신 문의사항을 확인해보니, 제 글에 오류가 있었네요.

1,2 번 모두 말씀해주신 부분이 맞습니다.

제 글을 꼼꼼하게 읽어주셔서 감사합니다! 위 내용은 수정하겠습니다 😊

BETTERFUTURE4 commented 1 year ago

queryFactory .selectFrom(user) .where(user.username.like("user_")) .fetch() .size(); 실행 시 count 쿼리가 날아가지 않는 거로 보이는데 성능 이슈는 없을까요?

devwithpug commented 1 year ago

@BETTERFUTURE4 안녕하세요. 꼼꼼하게 읽어주셔서 감사합니다!

글에 작성된 로직은 querydsl 5.0.0 버전부터 fetchCount()가 deprecated 되면서, count 쿼리를 날리지 않고 select 쿼리로 가져온 데이터의 total count를 메모리에서 계산하는 방법입니다, 따라서 count 쿼리가 날아가는 것은 아닙니다.

쿼리 조건에 따라 성능 이슈는 존재할 수 있지만, 어떤 데이터를 조회하는지, 어떤 인덱스를 태우는지 필터되는 카디널리티 등등.. 실제 프로덕션에서는 더 깊은 고민이 필요하고 적절한 방법을 찾아서 적용해야 할 것 같습니다. 이 글은 튜토리얼정도로 봐주시면 감사하겠습니다 😅

방법을 찾아보면 querydsl 릴리즈 노트에서는 아래와 같은 방법을 제안하고 있는데, 이 부분을 참고해보셔도 좋을 것 같습니다.

Deprecations AbstractJPAQuery#fetchResults and AbstractJPAQuery#fetchCount are now deprecated for queries that have multiple group by expressions or a having clause, because these scenarios cannot be supported by pure JPA and are instead computed in-memory. If the total count of results is not necessary, we recommend to always use AbstractJPAQuery#fetch instead. If you want a reliable way of computing the result count for a paginated result for even the most complicated queries, we recommend using the Blaze-Persistence QueryDSL integration. BlazeJPAQuery properly implements both fetchResults and fetchCount and even comes with a page method. getConstantToLabel which was deprecated in QueryDSL 4.3.0 is no longer deprecated.

http://querydsl.com/releases.html