2020-devbie icon indicating copy to clipboard operation
2020-devbie copied to clipboard

[Refactor] 공고 조회에서 불필요한 쿼리문 제거

Open hongbin-dev opened this issue 4 years ago • 3 comments

Resolve #320

  • 공고에서 applyPagination()을 사용함에도 offset, limit를 사용하고 있다.

Changes

  • 해당 코드를 제거한다.

Notes

  • applyPagination()는 QuerydslRepositorySupport에서 지원하는 메소드인데, pageable객체를 넣으면 페이징처리를 손쉽겧 ㅐ준다.
  • 현재 fetch join과 paging을 같이 하고 있는데, 이부분이 이슈가 있다.
  • fetch join을하고 limit를 하면 테이블 풀 스캔이 일어난다. (+ default_batch_fetch_size = 옵션을 줘야한다.)
    • 장점은 n+1문제를 잡을 수 있다. 단점은 테이블 풀 스캔이 일어나고, 데이터를 서버에서 받아 하이버네이트가 limit를 걸어준다.
  • fetch join을 하지 않고 limit를 하면 n+1문제가 생긴다.
    • 장점은 데이터베이스에 서버로 대용량 데이터를 넘겨주지않는다. 단점은 n+1쿼리가 일어난다...!ㅠㅠ

References

hongbin-dev avatar Oct 07 '20 02:10 hongbin-dev

결론적으로는 어떻게 해결하신건가요? 이거 질문쪽 코드 참고해서 말쓰드리자면, fetchJoin() 이 줄만 삭제하면 페이징하면서 n+1 문제도 피할 수 있을 것 같습니다!

yeonnseok avatar Oct 07 '20 08:10 yeonnseok

@yeonnseok 지금은 1번의 쿼리로 하이버네이트(서버)에서 limit를 해주고 있도록 했어요.

fetchJoin()을 빼게되면 notice와 languages와 1:N관계를 맺고 있어서 n+1 query가 일어나는 것 같은데, 제가 잘못이해하고 있는 걸까요?

hongbin-dev avatar Oct 07 '20 13:10 hongbin-dev

@khb1109 limit를 한다는게, 하이버네이트에서 페이지네이션을 한다는 말이시죠? 그렇게 되면 아마 콘솔에 warn 로그가 찍힐 것 같습니다. (안찍힌다면 알려주세요!) fetchJoin으로 1개의 쿼리로 가져오는걸 포기하고, default_batch_fetch_size 속성을 사용하면 2번의 쿼리로 지연로딩을 가져올 수 있습니다.

yeonnseok avatar Oct 12 '20 02:10 yeonnseok