Eager Loadingとクエリスコープ
Eager LoadingでN+1クエリを防ぎ、クエリスコープでロジックを再利用します
「Eager Loadingとクエリスコープ」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。
N+1 問題
ループ内でリレーションシップにアクセスすると、遅延読み込みによってモデルごとに 1 回のクエリが実行されます。大規模な環境では致命的な問題になります。
<?php
$posts = Post::all(); // 1 query
foreach ($posts as $post) {
echo $post->author->name; // 1 query per post = N+1 total!
}with() による Eager Loading
あらかじめ追加の 1 クエリでリレーションシップを Eager Loading することで、N+1 問題を解決します。
<?php
$posts = Post::with("author")->get(); // 2 queries total
foreach ($posts as $post) {
echo $post->author->name; // no extra query
}複数のリレーションシップの Eager Loading
複数のリレーションシップを一度に読み込みます。
<?php
$posts = Post::with(["author", "tags", "comments"])->get();ネストした Eager Loading
ドット記法を使用して、ネストしたリレーションシップを読み込みます。
<?php
$posts = Post::with("comments.author")->get();
// Loads posts, their comments, and each comment's author条件付き Eager Loading
Eager Loading するリレーションシップに条件を適用します。
<?php
$posts = Post::with(["comments" => function ($q) {
$q->where("approved", true)->latest();
}])->get();withCount()
関連モデル自体を読み込まずに、関連モデルの件数を読み込みます。
<?php
$posts = Post::withCount("comments")->get();
foreach ($posts as $post) {
echo $post->comments_count;
}遅延 Eager Loading(load())
load() を使用すると、すでに取得したコレクションに対してリレーションシップを Eager Loading できます。
<?php
$posts = Post::all();
// Later, when you know you need the authors:
$posts->load("author");グローバルクエリスコープ
グローバルスコープは、モデルに対するすべてのクエリに制約を自動的に追加します。
<?php
class PublishedScope implements \Illuminate\Database\Eloquent\Scope {
public function apply(Builder $builder, Model $model): void {
$builder->where("is_published", true);
}
}ローカルクエリスコープ
ローカルスコープは、モデル上で scope を接頭辞とするメソッドとして定義する、再利用可能なクエリ制約です。
<?php
class Post extends Model {
public function scopePublished(Builder $query): void {
$query->where("is_published", true);
}
public function scopeByUser(Builder $query, int $userId): void {
$query->where("user_id", $userId);
}
}
// Usage:
Post::published()->byUser(1)->latest()->get();スコープの組み合わせ
複数のローカルスコープを連結すると、読みやすく再利用可能なクエリロジックを構築できます。
<?php
$posts = Post::published()
->byUser(auth()->id())
->orderBy("created_at", "desc")
->paginate(15);開発中の N+1 の検出
Laravel Debugbar を使用するか、DB::enableQueryLog() を実行して、開発中に予期しないクエリ数を検出します。
まとめ
with() を使用してリレーションシップを Eager Loading し、N+1 クエリを解消します。件数には withCount() を使用します。再利用しやすく読みやすいクエリ制約には、ローカルスコープを定義します。
確認問題
N+1 問題を解決するために関連モデルを Eager Loading するメソッドはどれですか?
よくある質問
「Eager Loadingとクエリスコープ」レッスンは無料ですか?
はい。「Eager Loadingとクエリスコープ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。
「Eager Loadingとクエリスコープ」で何を学びますか?
Eager LoadingでN+1クエリを防ぎ、クエリスコープでロジックを再利用します ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
PHP Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Eager Loadingとクエリスコープ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPHP Academyレッスンでコードを書いて実行できますか?
はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Eloquentモデルとマイグレーション
- EloquentでCRUD
- Eloquentのリレーションシップ
- Eager Loadingとクエリスコープ