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

Форматування SQL

Зробити читабельним запит із toSql() або логів

Дані надсилаються на сервер, але не зберігаються

Цей інструмент не можна виконати у браузері, тому введені дані надсилаються на наш сервер. Ми обробляємо їх у пам'яті та одразу повертаємо результат: нічого не записується в базу, у файли чи в логи, нічого не передається третім сторонам. Та все ж не вставляйте сюди справжні робочі паролі чи ключі - для чутливих даних краще скористатися локальними інструментами.

Поділитись

Звідки береться нечитабельний SQL

Запит, який згенерував Eloquent, приходить одним рядком - з toSql(), з Telescope, з логу повільних запитів або з EXPLAIN. Поки в ньому три умови, це терпимо; на п'яти джойнах і підзапиті прочитати його очима вже неможливо.

Інструмент лише переформатовує текст. Запит не виконується - тож вставити сюди продакшн-статемент безпечно, нічого нікуди не піде.

Звідки взяти запит у Laravel

// Рядок запиту без прив'язок
User::where('is_active', true)->orderBy('name')->toSql();

// Запит разом зі значеннями - зазвичай саме це і потрібно
User::where('is_active', true)->toRawSql();

// Вивести і зупинитися
User::where('is_active', true)->dd();

toRawSql() з'явився в Laravel 10 і замінив ручне склеювання toSql() з getBindings(). Саме його результат зручно вставити сюди.

// Усі запити запиту в лог - корисно, коли джерело невідоме
DB::listen(function ($query) {
    logger($query->sql, ['bindings' => $query->bindings, 'time' => $query->time]);
});

Навіщо великі літери

Ключові слова капсом - домовленість, а не вимога: SQL їх не розрізняє. Але вона робить структуру видимою з першого погляду - де SELECT, де FROM, де починається WHERE.

Тут капс робиться через токенізатор, а не заміною по тексту. Різниця принципова: у запиті where name = 'select from where' слова всередині лапок - це дані, і чіпати їх не можна. Пошук-заміна цього не розрізняє, токенізатор розрізняє.

Що видно на відформатованому запиті

Декартів добуток - джойн без умови: FROM users, posts замість JOIN ... ON.

N+1 у логах - той самий SELECT із різним id, повторений сто разів. У відформатованому вигляді це помітно одразу.

// Причина: звернення до зв'язку в циклі
$posts = Post::all();
foreach ($posts as $post) { echo $post->author->name; }

// Виправлення
$posts = Post::with('author')->get();

SELECT * там, де треба два поля. На широкій таблиці це зайвий трафік і зайва пам'ять:

User::select('id', 'name')->get();

WHERE по колонці без індексу - видно за поєднанням із EXPLAIN. Форматування саме не покаже плану, але дає прочитати, які саме колонки у фільтрі.

Стиснення

Зворотна операція - прибрати переноси й зайві пробіли. Знадобиться, коли запит треба покласти в один рядок: у конфіг, у JSON, у команду psql -c.