Ой, ничего не найдено!

К сожалению, по вашему запросу пока ничего нет (но это только пока!), зато вы можете подписаться на нашу замечательную email-рассылку, чтобы не пропустить самое интересное в будущем.

  • 165

7 уровней оптимизации Laravel: от новичка до мастера-фокусника

  • 3 минуты на чтение

Как сэкономить до 98% ресурсов, или как превратить простой Laravel-код в магию, которую мало кто осмелится трогать?

Готовьтесь: мы отправимся в увлекательное путешествие по ступеням оптимизации в Laravel. От наивного «лишь бы всё работало» до уверенного «коллеги либо назовут вас волшебником, либо обвинят в шаманстве». Поехали!

Уровень 1: Первый шаг — жадная загрузка (Eager Loading)

Всё начинается с классики. Вы только-только узнали, что такое with(), и чувствуете себя героем: никакого N+1, только два запроса — и все данные под рукой.

use App\Models\Post;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::with('user')->get();
    return view('posts', ['posts' => $posts]);
});

Результат: Для 100k постов затрачиваем 191 МБ и примерно 0,63 сек. Итоговый «коэффициент ресурсоёмкости» — 120 единиц (условно). Неплохо, но не идеально.

Уровень 2: Первые серьёзные шаги — «А точно ли нужны все эти поля?»

Эксклюзивно для читателей: полгода бесплатного хостинга!
Заберите свой промокод FREE6MONTH и воспользуйтесь всеми преимуществами премиум-хостинга бесплатно.

Далее вы задумались: зачем вытаскивать всё подряд? Ограничьте выборку до нужных столбцов, и уже почувствуете разницу.

use App\Models\Post;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::with('user:id,name')
                 ->select('id','user_id','title')
                 ->get();
    return view('posts', ['posts' => $posts]);
});

Результат: Минус 20% ресурсоёмкости. Конечно, вы ещё не спасли мир, но уже выглядите более профессионально.

Уровень 3: Переход на ручное управление — разделяем запросы

Теперь вы идёте дальше. Вместо жадной загрузки — два отдельных запроса: один для постов, другой для пользователей. В итоге вы создаёте своего рода таблицу соответствий.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::select('id','user_id','title')->get();
    $users = User::whereIn('id', $posts->pluck('user_id')->unique())
                 ->pluck('name', 'id');
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Ещё +15% эффективности. Вы уже пьёте кофе с лёгкой улыбкой превосходства.

Уровень 4: Попытка хитрить с distinct

Получите 6 месяцев бесплатного хостинга!
Воспользуйтесь нашим промокодом FREE6MONTH и начните свой проект без лишних затрат.

Вы пытаетесь доверить часть оптимизации базе данных: пусть она сама выберет уникальные значения user_id. Результаты? Есть прирост по времени, но с памятью особого выигрыша нет.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = (clone $query)->select('id', 'user_id', 'title')->get();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Быстрее, но ощутимого облегчения памяти нет. Что ж, оптимизация — это путь проб и ошибок.

Уровень 5: Скрытая магия — toBase()

Вы обнаружили toBase(), который пропускает всю «магию» Eloquent, оставляя только «чистые» результаты. И вот тут начинается серьёзный прорыв.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = (clone $query)->select('id','user_id','title')
                           ->toBase()
                           ->get();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->toBase()
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Минус 85% ресурсоёмкости. Теперь вы чувствуете себя настоящим гуру Laravel.

Уровень 6: Ещё шаг — chunkById

Получите 6 месяцев бесплатного хостинга!
Воспользуйтесь нашим промокодом FREE6MONTH и начните свой проект без лишних затрат.

Время применить «чанкование». Вы загружаете данные порционно и аккуратно складываете их в коллекцию. К примеру, по 15 000 записей.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = collect();
    (clone $query)->select('id', 'user_id', 'title')
                  ->toBase()
                  ->orderBy('posts.id')
                  ->chunkById(15000, function ($collection) use (&$posts) {
                      $posts->push(...$collection);
                  }, 'id');
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->toBase()
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Ещё плюс 14% к оптимизации. Кажется, вы уже приблизились к пределу.

Уровень 7: Высший пилотаж — Lazy Collections

Финальный козырь в рукаве — lazyById(). Представьте себе chunkById, но более «ленивый» и гибкий. Вы загружаете данные партиями (например, по 10 000), удерживая их в памяти по мере необходимости.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->pluck('name', 'id');
    $posts = (clone $query)
                 ->select('id', 'user_id', 'title')
                 ->toBase()
                 ->lazyById(10000, 'id');
    return view('welcome', [
        'posts' => $posts,
        'users' => $users,
    ]);
});

Результат: Память используется ещё более экономно. Вы стоите на вершине горы оптимизации, смотрите свысока на затраты ресурсов и понимаете, что сократили их примерно на 98% (с 120 до 2,4). Ваши коллеги в шоке — либо восхищены, либо озадачены тем, что вы сотворили.

Итог:

Эксклюзивно для читателей: полгода бесплатного хостинга!
Заберите свой промокод FREE6MONTH и воспользуйтесь всеми преимуществами премиум-хостинга бесплатно.

Вы прошли путь от новичка, довольствующегося eager loading, до мастера, выжимающего из Laravel максимум. Но не забывайте, с чего вы начинали. И не удивляйтесь, если через секунду ваш начальник влетит с вопросом: «А как там прогресс по остальным задачам?» Вы сэкономили серверные ресурсы — но кто сэкономит ваше время теперь?

Хостинг, на который можно положиться!
Siteko.net

Устали от медленного хостинга или дорогих тарифов? Тогда вам к нам! Siteko.net — это быстрый и простой хостинг для тех, кто ценит удобство и стабильность.

  • Без падений и нервов — наш uptime почти всегда 100%.
  • Гибкие тарифы — только нужные функции, ничего лишнего.
  • Скорость— сайты грузятся, как пуля!
  • Удобно — разобраться сможет даже новичок, всё под рукой.
  • Поддержка всегда рядом 24/7 поможем решить любой вопрос.

Заходите на Siteko.net и попробуйте нас бесплатно первый месяц! Мы делаем всё, чтобы ваш сайт работал без проблем.

Siteko.net — просто, быстро и надёжно!