Оптимізаторні підказки - коментарі спеціального вигляду одразу після ключового слова SELECT, UPDATE, DELETE чи INSERT. Вони керують оптимізатором точніше, ніж старі FORCE INDEX, і можуть стосуватися окремого запиту, таблиці чи індексу.
SELECT /*+ MAX_EXECUTION_TIME(2000) */ * FROM reports WHERE ...;
Основні групи:
- індекси:
INDEX(t idx),NO_INDEX(t idx), точніше -JOIN_INDEX,ORDER_INDEX,GROUP_INDEX; такожINDEX_MERGE/NO_INDEX_MERGE,SKIP_SCAN,NO_ICP,NO_RANGE_OPTIMIZATION; - порядок з'єднань:
JOIN_ORDER(a, b),JOIN_PREFIX(a),JOIN_SUFFIX(b),JOIN_FIXED_ORDER(); - стратегії з'єднань і підзапитів:
BNL/NO_BNL(керують і хеш-з'єднанням),BKA,SEMIJOIN(FIRSTMATCH),SUBQUERY(MATERIALIZATION),MERGE/NO_MERGEдля похідних таблиць; - виконання:
MAX_EXECUTION_TIME(мс)(лише дляSELECT),SET_VAR(змінна=значення)- змінна сесії лише на час запиту,RESOURCE_GROUP(...).
Найкорисніші на практиці:
-- обмежити час важкого звіту, щоб не тримав сервер
SELECT /*+ MAX_EXECUTION_TIME(5000) */ ...;
-- більший буфер сортування лише для цього запиту
SELECT /*+ SET_VAR(sort_buffer_size = 16777216) */ ... ORDER BY ...;
-- не матеріалізувати похідну таблицю, а злити з зовнішнім запитом
SELECT /*+ MERGE(t) */ * FROM (SELECT ...) AS t WHERE ...;
Переваги над FORCE INDEX:
- неправильна підказка не ламає запит - MySQL видає попередження й ігнорує її (а
FORCE INDEXз неіснуючим індексом дає помилку); - для інших СУБД це просто коментар - менше зав'язки на синтаксис MySQL;
- точкове керування без зміни змінних сесії.
У Laravel підказка має стояти одразу після SELECT. Найпростіше - через selectRaw першим виразом:
Report::query()
->selectRaw('/*+ MAX_EXECUTION_TIME(5000) */ *')
->where('year', 2026)
->get();
Підказки в коментарях не мають бути «з'їдені» по дорозі: деякі проксі й інструменти мініфікації SQL вирізають коментарі - це варто перевірити в EXPLAIN чи журналі запитів.
Як перевірити, що підказку застосовано: EXPLAIN і SHOW WARNINGS після нього - там видно переписаний запит з підказками, а нерозпізнані підказки дають попередження.
Застереження те саме, що й для будь-яких підказок: вони заморожують рішення. MAX_EXECUTION_TIME і SET_VAR - безпечні запобіжники; підказки індексів і порядку з'єднань - крайній засіб із коментарем, чому вони там.