Андрій Кравець

Індекси в MySQL: чому запит повільний, хоча індекс є

«Але ж там є індекс!» — типова фраза перед тим, як розробник дивиться на повільний запит. Індекс не гарантує швидкості: MySQL сам вирішує, чи користуватися ним. Розберемо найчастіші причини, чому індекс не працює, і як це перевірити.

Починайте з EXPLAIN

Перед будь-якою оптимізацією запустіть запит із EXPLAIN. Дивіться на три колонки.

  • key — який індекс вибрано. NULL означає, що жодного.
  • rows — скільки рядків база збирається прочитати.
  • type — ALL означає повне сканування таблиці, ref чи range — уже непогано.
EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'paid' ORDER BY created_at DESC LIMIT 20;

Причина 1: порядок колонок у складеному індексі

Індекс (status, user_id) не допоможе запиту, який фільтрує лише за user_id: працює правило «лівого префікса». Спершу ставте колонки, які порівнюються на рівність, потім ту, за якою сортуєте.

Причина 2: функція над колонкою

Умова WHERE DATE(created_at) = '2026-10-01' змушує рахувати функцію для кожного рядка. Перепишіть діапазоном: created_at >= '2026-10-01' AND created_at < '2026-10-02'.

Причина 3: LIKE з відсотком попереду

LIKE 'абв%' використовує індекс, а LIKE '%абв' — ні. Для пошуку всередині тексту потрібен повнотекстовий індекс чи окремий пошуковий рушій.

Причина 4: різні типи й кодування

Порівняння числа з рядком чи різних кодувань змушує базу перетворювати значення й відмовлятись від індексу. Тримайте тип у запиті таким самим, як у колонці.

Причина 5: індекс просто не вигідний

Якщо умова відбирає значну частину таблиці (наприклад, 40% рядків), сканувати таблицю дешевше, ніж стрибати за індексом. Це нормально, тож не додавайте індекс на колонки з двома-трьома різними значеннями.

Контрольний список

  1. Знайдіть повільний запит у журналі повільних запитів.
  2. Запустіть EXPLAIN, подивіться key і rows.
  3. Додайте або змініть індекс, повторіть EXPLAIN.
  4. Заміряйте реальний час, а не лише план: рівно на ваших даних.

Коментарі

Поки без коментарів.