プリロードの最適化 Laravel モデルのクエリ関連の問題の詳細な説明

巴扎黑
リリース: 2023-03-14 22:12:01
オリジナル
1263 人が閲覧しました

この記事では主に、プリロードを使用して Laravel モデルのクエリを最適化する方法に関する関連情報をサンプル コードを通じて詳しく紹介します。この記事は、学習や作業に必要な学習に役立ちます。以下で一緒に学びましょう。

前書き

この記事では主に、Laravel モデルのクエリを最適化するためのプリロードの使用に関する関連コンテンツを紹介し、参照と学習のために共有します。

はじめに

オブジェクト リレーショナル マッピング (ORM) を使用すると、データベースの操作が非常に簡単になります。 データベースの関係がオブジェクト指向の方法で定義されている場合、関連するモデル データを簡単にクエリでき、開発者は基礎となるデータベースの呼び出しに気付かない可能性があります。

以下では、クエリを最適化する方法をさらに理解するためにいくつかの例を使用します。

データベースから 100 個のオブジェクトを受け取り、各レコードに 1 つの関連付けられたモデル (つまり、belongsTo) があるとします。 デフォルトで ORM を使用すると、以下に示すように 101 個のクエリが生成されます:


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

$authors = array_map(function($post) {
 // 对作者模型生成查询
 return $post->author->name;
}, $posts);
ログイン後にコピー

クエリ時にすべての作成者も必要であることを Post モデルに伝えていないため、毎回 1 つの作成者から作成者の名前を取得します。モデル インスタンスの後、別のクエリが発生します。

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 ログをオンにすると、上記のプリロードによって 2 つのクエリのみが生成されることがわかります:


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;
});
ログイン後にコピー

上記の

に 100 レコードがあると仮定すると、いくつのクエリが生成されるでしょうか? AppPost::with('author')->get()

積極的な読み込みを最適化することで、ネストされた関係における余分なクエリを回避できます。


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

$posts->map(function ($post) {
 //不在产生新查询
 return $post->author->profile;
});
ログイン後にコピー

SQL ログを開いて、対応する 3 つのクエリを確認できます。


select * from `posts` 
select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [.....] 
select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [.....]
ログイン後にコピー

遅延読み込み

場合によっては、条件に基づいて関連モデルを収集する必要がある場合があります。 この場合、関連データに対して他のクエリを遅延呼び出しできます:


$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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート