>백엔드 개발 >PHP 튜토리얼 >사전 로딩 최적화 Laravel 모델 쿼리 관련 문제에 대한 자세한 설명

사전 로딩 최적화 Laravel 모델 쿼리 관련 문제에 대한 자세한 설명

巴扎黑
巴扎黑원래의
2017-08-12 11:44:121283검색

이 글에서는 미리 로딩을 사용하여 Laravel 모델 쿼리를 최적화하는 방법에 대한 관련 정보를 주로 소개합니다. 샘플 코드를 통해 이를 매우 자세하게 소개하며, 학습이나 작업이 필요한 모든 사람이 따라할 수 있는 학습 가치가 있습니다. 아래에서 함께 배워봅시다.

머리말

이 글은 주로 사전 로딩을 사용하여 Laravel 모델 쿼리를 최적화하는 방법에 대한 관련 내용을 소개하고 참조 및 학습을 위해 공유합니다. 자세한 소개는

소개

ORM(객체 관계형 매핑)을 사용하면 데이터베이스 작업이 매우 쉬워집니다. 데이터베이스 관계가 객체 지향 방식으로 정의되면 관련 모델 데이터를 쉽게 쿼리할 수 있으며 개발자는 기본 데이터베이스 호출을 알아차리지 못할 수 있습니다.

다음에서는 쿼리 최적화 방법을 이해하는 데 도움이 되는 몇 가지 예를 사용합니다.

데이터베이스에서 100개의 개체를 받았고 각 레코드에 1개의 관련 모델(예: ownTo)이 있다고 가정합니다. 기본적으로 ORM을 사용하면 아래와 같이 101개의 쿼리가 생성됩니다.


//获取已发布的100条文章
$posts = Post::limit(100)->get(); //一次查询

$authors = array_map(function($post) {
 // 对作者模型生成查询
 return $post->author->name;
}, $posts);

쿼리 시 Post 모델에 모든 작성자도 필요하다는 사실을 알려주지 않았기 때문에 매번 단일 항목에서 작성자의 이름을 가져옵니다. 모델 인스턴스 이후에는 별도의 쿼리가 발생합니다.

array_maps 100개의 쿼리가 발생했고, 이전 쿼리까지 더해 총 101개의 쿼리가 생성되었습니다.

사전 로드

다음으로, 연관된 모델 데이터를 사용할 계획이라면 사전 로드를 사용하여 총 101개의 쿼리를 2개의 쿼리로 줄일 수 있습니다. 로드해야 할 사항을 모델에 알려주십시오. 다음과 같습니다:


//获取已发布的100条文章 - 并预加载文章对应作者
$posts = Post::with('author')->limit(100)->get();//2次查询

$authors = array_map(function($post) {
 // 对作者模型生成查询
 return $post->author->name;//这里讲不在产生查询
}, $posts);

SQL 로그를 켜면 위의 사전 로드가 두 개의 쿼리만 생성하는 것을 볼 수 있습니다.


select * from `posts`
select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [1,2,3,4,5]

관련 모델이 여러 개 있는 경우 배열을 사용하여 로드할 수 있습니다. :


$posts = App\Post::with(['author', 'comments'])->get();

다음으로 다음 관계를 재정의합니다


Post -> belongsTo -> Author //每个文章只属于一个用户
Author -> hasMany -> Post //每个用户拥有多个文章
Author -> hasOne -> Profile //每个用户只有一个简介

다음 상황을 고려해보세요. 게시된 기사 작성자의 개인 프로필을 가져옵니다.


//获取所有文章 - 并预加载文章对应作者
$posts = App\Post::with('author')->get();//两次查询

//根据每个 `作者` 获取其简介
$posts->map(function ($post) {
 //虽然我们直接通过$author = $post->author不会产生查询,
 //但当调用$author->profile时,每次都会产生一个新查询
 return $post->author->profile;
});

위의 AppPost::with('author')->get()에 100개의 레코드가 있다고 가정하면 몇 개의 쿼리가 생성됩니까?

즉시 로딩을 최적화하면 중첩 관계에서 추가 쿼리를 피할 수 있습니다.


//获取所有文章 - 并预加载文章对应作者及每个作者对应de profile
$posts = App\Post::with('author.profile')->get();//三次查询

$posts->map(function ($post) {
 //不在产生新查询
 return $post->author->profile;
});

SQL 로그를 열어 해당하는 세 가지 쿼리를 확인할 수 있습니다.


select * from `posts` 
select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [.....] 
select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [.....]

Lazy loading

때로는 조건에 따라 관련 모델을 수집해야 할 수도 있습니다. 이 경우 관련 데이터에 대해 다른 쿼리를 느리게 호출할 수 있습니다.


$posts = App\Post::all();//一次查询

$posts->load('author.profile');//两次查询
$posts->map(function ($post) {
 //不在产生新查询
 return $post->author->profile;
});

SQL 로그를 보고 총 3개의 쿼리를 확인하세요. 그러나 $posts->load()가 show라고 호출되는 경우에만 해당됩니다.

결론

모델 로딩에 대해 더 많이 알고 더 깊은 수준에서 작동하는 방식을 이해하길 바랍니다. Laravel과 관련된 문서는 이미 매우 포괄적입니다. 추가적인 실습을 통해 관계형 쿼리를 최적화하는 데 더욱 자신감을 가질 수 있기를 바랍니다.

요약

원문은 eloquent-eager-loading을 번역하여 데이터 구성의 이전 부분을 단순화합니다.

위 내용은 사전 로딩 최적화 Laravel 모델 쿼리 관련 문제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.