요구 사항으로
한 페이지에 게시글을 10개 가져오는 데
댓글은 최신순 3개정도만 미리보기로 가져온다고 생각해봐
List 게시글 = select * from 게시글 join 댓글 limit 0, 10
이러면 페이징이 조인 결과에 따라
게시글1 - 댓글1
게시글1 - 댓글2
게시글1 - 댓글3
이게 행 3개를 잡아 먹음
쿼리 결과가 게시글이 10개가 안나옴
요구사항에 맞지않음
이걸 피하려고
List 게시글 = select * 게시글 limit 0,10
for(a : 게시글){
List 댓글 = select 댓글 where 댓글.게시글=a limit 0,3
a.set(댓글)
}
이렇게 짜면 N+1 터지는거지
근데 이게 직관적이니깐 이렇게 짤 수도 있는거임
쿼리 하나로 게시글10개+각 게시글당 댓글 최신 3개(없으면 댓글쪽은 null)까지 가능?
밑에 다른 분 제시한 로우 넘버 기반 해결법 첨부함
저렇게 짜는놈이 있나 아무리 대충짜도 게시글은 서브쿼리로 따로가져오지
댓글도 최신3개까지 같이 가능? - dc App
동시에 2개 테이블 페이징해야함 - dc App
게시글 10개 가져온거랑 조인해서 댓글 로우넘버 매겨서 3개까지 가져오면 되잖음
그러게 로우넘버로 되긴하네 - dc App
역시 딘퐁이야. 그래서 보통 in 절 써서 쿼리 2개로 가져옴. 장고에서 쓰는 prefetch_related가 같은 맥락. 1. 글 10개 가져오기 2. 글 아이디로 댓글 가져오기 (IN)
나도 요구사항 보자마자 쿼리 2개로 날리는거 생각했었는데 jpa 안 쓰고 그냥 쌩쿼리로 날려버릇하면 저런 for문으로 쿼리 반복해서 가져온다는 생각 자체를 안 하게 되나봐 어쨌든 본문 요구사항 for문 예시는 정말 좋당
근데 in쓰면 각 게시글당 최대 3개를 만족할 수 있나 - dc App
막줄을 안봤는데 꽤 빡세노
batch fetching - dc App
각 게시글당 최대 3개도 만족하냐? - dc App
서브쿼리써야하낭 생각해보니 그런용도는 batch에서 못써 - dc App
WITH ARTICLE_L AS (SELECT * FROM 게시글 ORDER BY CREATE_DATE DESC FETCH FIRST 10 ROWS ONLY )SELECTL.*, C.* FROMARTICLE_L L JOIN (SELECT * FROM ( SELECT C2.*,ROW_NUMBER() OVER (PARTITION BY ARTICLE_IDORDER BY CREATE_DATE DESC) AS RNFROM 댓글 C2JOIN ARTICLE_L L2 ON C2.ARTICLE_ID = L2.ID ) XWHERE RN <= 3) CON L.ID = C.ARTICLE_ID;
직접 적어서 띄어쓰기 없는거 죄송요...