Форматування 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.
- Де виконується
- на сервері
- Категорія
- Дані та формати