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

Як побачити SQL, який генерує Eloquent, і знайти зайві чи повільні запити?

Подивитися SQL одного запиту без виконання:

User::where('active', true)->orderBy('name')->toSql();
// select * from "users" where "active" = ? order by "name" asc

User::where('active', true)->toRawSql();
// select * from "users" where "active" = 1 ...   - з підставленими значеннями

Вивести й продовжити чи зупинитися:

User::where('active', true)->dumpRawSql()->get();  // вивести й виконати
User::where('active', true)->ddRawSql();           // вивести й зупинити

toRawSql() зручний, щоб скопіювати запит у консоль бази й запустити EXPLAIN. Але для реального виконання Laravel завжди використовує підготовлені запити з окремими параметрами - підставлені значення лише для читання людиною.

Усі запити за запит чи команду:

DB::enableQueryLog();
// ... код ...
dump(DB::getQueryLog());   // SQL, параметри й час кожного

Слухач запитів - для логування в розробці:

// AppServiceProvider::boot()
if (app()->isLocal()) {
    DB::listen(function (QueryExecuted $query): void {
        Log::debug($query->toRawSql(), ['ms' => $query->time]);
    });
}

Сповіщення про повільну роботу з базою за весь запит:

DB::whenQueryingForLongerThan(500, function (Connection $connection, QueryExecuted $event): void {
    Log::warning('Багато часу в базі', ['connection' => $connection->getName()]);
});

Як знайти проблеми системно:

  • N+1: Model::preventLazyLoading(! app()->isProduction()) - виняток при лінивому завантаженні зв'язку в циклі;
  • Laravel Debugbar чи Telescope - список запитів сторінки з дублікатами й часом;
  • сторінка помилки Laravel також показує виконані запити;
  • на продакшені - журнал повільних запитів бази (pg_stat_statements, slow query log), а не логування кожного запиту.

Пастка: enableQueryLog у довгому процесі (воркер, команда з мільйоном записів) накопичує всі запити в пам'яті - вмикайте його лише на час налагодження.

Докладніше в документації: Налагодження запитів

Схожі питання