0Pricing
PHP Academy · Урок

Предварительная загрузка и области запросов

Предотвращайте запросы 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 — локальная установка не требуется.

Все уроки этого курса

  1. Модели и миграции Eloquent
  2. CRUD с Eloquent
  3. Связи Eloquent
  4. Предварительная загрузка и области запросов
← Назад к PHP Academy