Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти
Інше
Події Про нас

Tips & Tricks: статті за тегом «Оптимізація запитів»

Статті, новини, туторіали та переклади від учасників спільноти

No results.
#optimizaciia-zapitiv Очистити фільтр
Tips 03 липня 2026

whereHas() vs whereRelation() - швидша фільтрація

Фільтруєш користувачів які мають пости? whereHas() створює підзапит.

whereRelation() використовує join. Швидше на великих таблицях.

Різниця в продуктивності:

  • whereHas() - підзапит для перевірки кожного рядка
  • whereRelation() - одна join операція

Коли використовувати:

Використовуй whereRelation() для простих умов на пов'язаних моделях. Використовуй whereHas() коли потрібна складна логіка або підрахунок.

Покращення Laravel 11:

whereRelation() додано в Laravel 8.57. Читабельніше ніж ручні join'и.

Порада: Для простих фільтрів зв'язків завжди віддавай перевагу whereRelation() над whereHas().

// ПОВІЛЬНО: Підзапит для кожного користувача
$users = User::whereHas('posts', function ($query) {
    $query->where('published', true);
})->get();

// ШВИДКО: Одна join операція
$users = User::whereRelation('posts', 'published', true)
    ->get();

// Декілька умов
$users = User::whereRelation('posts', 'published', true)
    ->whereRelation('posts', 'views', '>', 1000)
    ->get();

// Різні зв'язки
$users = User::whereRelation('posts', 'published', true)
    ->whereRelation('profile', 'verified', true)
    ->get();
// Коли ПОТРІБЕН whereHas() - складна логіка
$users = User::whereHas('posts', function ($query) {
    $query->where('published', true)
        ->where(function ($q) {
            $q->where('views', '>', 1000)
              ->orWhere('featured', true);
        });
})->get();

// Підрахунок зв'язків
$users = User::whereHas('posts', fn($q) =>
    $q->where('published', true), '>=', 5
)->get();

// orWhereRelation() також доступний
$users = User::whereRelation('posts', 'status', 'draft')
    ->orWhereRelation('posts', 'status', 'pending')
    ->get();
Tips 18 березня 2026

select() - припинити завантаження зайвих колонок

Завантаження повного рядка користувача з 20 колонками. Потрібні тільки ім'я та email.

База даних надсилає всі дані. Пам'ять витрачається. Запит повільніший.

Рішення:

Використовувати select() щоб вказати точні колонки. Швидші запити, менше пам'яті.

Важливо:

Завжди включай первинний ключ (id) щоб зв'язки працювали.

Просунуте:

Використовувати addSelect() щоб додати колонки до існуючого select.

Порада: Особливо важливо для таблиць з TEXT/BLOB колонками або таблиць з 20+ колонками.

// ПОГАНО: Завантажує всі колонки
$users = User::all();
foreach ($users as $user) {
    echo $user->name; // Інші 18 колонок витрачені даремно
}

// ДОБРЕ: Тільки те що потрібно
$users = User::select('id', 'name', 'email')->get();

// Додавати колонки динамічно
$query = User::select('id', 'name');
if ($needEmail) {
    $query->addSelect('email');
}

// Зі зв'язками - потрібні зовнішні ключі
$posts = Post::select('id', 'title', 'user_id')
    ->with('author:id,name')
    ->get();

// Агрегація без завантаження моделей
$totalViews = Post::sum('views');
$avgRating = Post::avg('rating');
$maxPrice = Product::max('price');