Предварительная загрузка и области запросов
Предотвращайте запросы N+1 с помощью предварительной загрузки и повторно используйте логику через области запросов
«Предварительная загрузка и области запросов» — бесплатный урок PHP Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения PHP Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс PHP Academy содержит 4 уроков всего.
Проблема N+1
Ленивая загрузка выполняет по одному запросу для каждой модели при обращении к связи внутри цикла — при масштабировании это приводит к катастрофическому снижению производительности.
<?php
$posts = Post::all(); // 1 query
foreach ($posts as $post) {
echo $post->author->name; // 1 query per post = N+1 total!
}Жадная загрузка с with()
Устраните проблему N+1, заранее загрузив связи одним дополнительным запросом.
<?php
$posts = Post::with("author")->get(); // 2 queries total
foreach ($posts as $post) {
echo $post->author->name; // no extra query
}Жадная загрузка нескольких связей
Загрузите сразу несколько связей.
<?php
$posts = Post::with(["author", "tags", "comments"])->get();Вложенная жадная загрузка
Загружайте вложенные связи с помощью точечной нотации.
<?php
$posts = Post::with("comments.author")->get();
// Loads posts, their comments, and each comment's authorЖадная загрузка с ограничениями
Применяйте условия к загружаемой связи.
<?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;
}Ленивая жадная загрузка (load())
Загружайте связи у уже полученной коллекции с помощью load().
<?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(), чтобы заранее загружать связи и устранять запросы N+1. Используйте withCount() для получения количества записей. Определяйте локальные области для повторно используемых и понятных ограничений запросов.
Быстрая проверка
Какой метод заранее загружает связанные модели, чтобы устранить проблему N+1?
Часто задаваемые вопросы
Урок «Предварительная загрузка и области запросов» бесплатный?
Да — полный текст урока «Предварительная загрузка и области запросов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс PHP Academy, подпишись на CoddyKit PRO. Курс PHP Academy содержит 4 уроков всего.
Чему я научусь в уроке «Предварительная загрузка и области запросов»?
Предотвращайте запросы N+1 с помощью предварительной загрузки и повторно используйте логику через области запросов Ты практикуешь PHP Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать PHP Academy?
Предыдущий опыт не требуется. PHP Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Предварительная загрузка и области запросов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке PHP Academy?
Да. Каждый урок PHP Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Модели и миграции Eloquent
- CRUD с Eloquent
- Связи Eloquent
- Предварительная загрузка и области запросов