질문을 삭제하지 말아주세요.!
 
1
0
-1

타임라인을 구현할 때

한 포스트가 너무 많은 코멘트를 가지고 있는 경우 문제가 될 수 있을 것 같습니다.

그래서 eager load 할 때 한 포스트당 최대 몇 개라는 식으로 가져오고 싶은데 아직 방법을 잘 모르겠네요.

위와 같이 하는 경우 각 코멘트당 10개가 아니라 전체에서 코멘트를 10개만 가져오더라구요.

$posts = Post::with(['comments' => function($query) {
	$query->take(10)->get();
}])->paginate(10);

아래와 같이 Post의 갯수만큼 쿼리를 날리면 되는 것이긴 한데, 왠지 잘못하는 것 같은 느낌이 들어서요. 한 번에 가능한 방법이 없나 싶어 문의드립니다.

$posts = Post::paginate(10);

foreach($posts as $post) {
	$post->load(['comments' => function($query) {
		$query->take(10)->get();
	}]);
}
    CommentAdd your comment...

    3 answers

    1.  
      1
      0
      -1

      eager loading 은 Post 10개일 경우, Comment 쿼리를 10개에서 1개로 줄이는데 사용하잖아요.


      그럼 쿼리문으로만 가능 여부를 판단해본다면...

      `Post 별로 댓글 10개 가져오기`를 위해서는 다음처럼 UNION 쿼리문이 필요해 보입니다.

      select * from comments where post_id=1 order by id desc limit 10
      UNION ALL
      select * from comments where post_id=2 order by id desc limit 10
      UNION ALL
      ...

      이런 UNION 쿼리의 사용은 eager loading 의 성능 향상 목적에 부합하지 않아 지원하지 않으리라 생각되고요.


      그럼 결국 두번째 예제처럼 foreach 로 Post 수만큼 쿼리를 실행하는 것이 현실적으로 맞는 방법 아닐까요?


        CommentAdd your comment...
      1.  
        1
        0
        -1

        간단한 문제인 줄 알고 봤는데 쉽지가 않네요. ㅠㅠ

        첫번째 코드의 쿼리는 다음처럼 찍힙니다.

        select count(*) as aggregate from `posts`
        select * from `posts` limit 10 offset 0
        select * from `comments` where `comments`.`post_id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10') limit 10
        
        
        


          CommentAdd your comment...
        1.  
          1
          0
          -1

          "위와 같이 하는 경우 각 코멘트당 10개가 아니라 전체에서 코멘트를 10개만 가져오더라구요."  부분은 이해하기 어렵네요.
          이렇게 쿼리하면 각 "포스트"당 코멘트 10개씩 가져오는 것 아닌가요? (실험해 보지는 않았습니다.)

          우선 $posts = ...→toSql() 로 해서 SQL 구문을 확인하는게 가장 확실할 것 같구요.

          트랜스포머를 쓰는 방법도 있으니 참고하세요. https://github.com/appkr/api/blob/master/src/example/AuthorTransformer.php#L78-L79

          1. 이현석

            변용훈님이 답글 달아주신 것 처럼 쿼리가 

            select count(*) as aggregate from `posts`
            select * from `posts` limit 10 offset 0
            select * from `comments` where `comments`.`post_id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10') limit 10
            
            

            이런 식으로 날려지더라구요. 각 포스트당 10개씩이 아니라 포스트에 해당하는 코멘트 전체에서 10개를 가져오는 것이죠. 

          CommentAdd your comment...