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

Статті за тегом «Оптимізація запитів»

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

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');