2017-11-19 17 views
1

열심히로드하는 데있어 laravel의 방법이 무엇인지 이해하지 못하고 N + 1 쿼리의 문제를 해결하고 어떤 문제가 발생하는지 이해할 수 없습니다. 그래서 나는 결과를보기 위해 스스로 테스트를 결정했습니다!lagervel 5.5에서 열심히 로딩 충돌

그래서 모든 tgchannel (전보 채널)에 많은 태그가 있고 모든 태그에는 많은 tgchannel이있는 간단한 다 대다 관계를 만들었습니다.

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class tgchannel extends Model 
{  
    public function tags() { 
     return $this->belongsToMany('App\tag'); 
    } 
} 

/////////////////////////////

class tag extends Model 
{ 
    // 
    public function tgchannels() { 
     return $this->belongsToMany('App\tgchannel'); 
    } 

나는 태그를로드하는 열망로드를 사용 이 기술 laravel 문서 출력 결과 SQL에 따른 제어 방법의 관계 : 시험 데이터베이스

public function test() 
{ 
    $all_channels = tgchannel::with(['tags'])->toSql(); 
    echo $all_channels.'<br>'; 

    $all_channels = tgchannel::with(['tags'])->get(); 

    foreach ($all_channels as $channel) { 
     $sql = $channel->tags()->toSql(); 
     echo $sql.'<br>'; 
    } 

} 

는, I는 각각이 태그를 가지고 12 tgchannels 있었다. 그리고 마지막으로이 결과 :

select * from `tgchannels` 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 
select * from `tags` inner join `tag_tgchannel` on `tags`.`id` = `tag_tgchannel`.`tag_id` where `tag_tgchannel`.`tgchannel_id` = ? 

당신은 실행 쿼리가이 아니며, N + 1 개 쿼리 일반적인 게으른 로딩에 그와 유사한 실행되는 것을 볼 수 있습니다!

무엇이 문제입니까 ??

답변

2

는 대신로드 된 데이터를 사용하여 추가 쿼리를 만드는, 그래서 $channel->tags() 대신 $channel->tags 모음을 사용하고 있습니다 : 그냥 하나를 기록했다

foreach ($all_channels as $channel) { 
    echo 'Channel: ' . $channel->id . '<br>'; 
    foreach ($channel->tags as $tag) { 
     echo 'Tag: ' . $tag->id . '<br>'; 
    } 
} 
+1

. 그는이 문제를 해결했지만 여전히 오래된 함정에 빠져 들었습니다. –

+0

답장을 보내 주셔서 감사합니다.하지만 왜 첫 번째 쿼리의 출력은 "select * from tgchannels"입니다 ... 관계에 대한 정보가 없습니다! –