TGViewer
EvApps EvApps @evapps_team · 199 subscribers
Post #1518 110
🗄 Почему твой SQL-индекс молчит
Знакомая история: повесил индекс, а запрос как тормозил, так и тормозит.
Индекс вроде есть, но планировщик смотрит на него и проходит мимо.
Собрал самые частые причины, из-за которых так происходит.
1. Обернул колонку в функцию 🔧 Вот это ломает индекс чаще всего:
WHERE YEAR(created_at) = 2024

Как только колонка попадает внутрь функции, индекс по ней уже не применить — и привет, seq scan по всей таблице. Лечится диапазоном:
WHERE created_at >= '2024-01-01'
AND created_at < '2025-01-01'

Ну или заводишь функциональный индекс, если без функции совсем никак.

2. LIKE, который начинается с % 🔍 Тут всё просто:
WHERE name LIKE '%anton'   -- бесполезно
WHERE name LIKE 'anton%' -- работает

B-tree умеет искать по началу строки, а не по середине. Если тебе реально нужен поиск по куску внутри — это уже полнотекстовый индекс или триграммы (в постгресе pg_trgm).

3. Порядок колонок в составном индексе 📚 Индекс (a, b) устроен как телефонная книга: сначала сортировка по a, и только внутри неё по b. Поэтому запрос, где есть только b, его не подхватит:
INDEX (user_id, created_at)

WHERE user_id = 5 -- норм
WHERE user_id = 5 AND created_at… -- норм
WHERE created_at > … -- мимо, левого префикса нет


4. Типы не совпали 🎭 Классика, на которой все хоть раз спотыкались:
-- phone у нас VARCHAR
WHERE phone = 89991234567 -- число против строки, индекс мимо
WHERE phone = '89991234567' -- порядок

База молча приведёт типы сама, а заодно тихо выкинет индекс.
Так что следи, чтобы тип значения совпадал с колонкой.

5. Индекс на колонке, где всего два значения 🎲 is_active, gender и прочие флаги индексировать почти бессмысленно.
Если под условие подходит половина таблицы, планировщику дешевле прочитать её целиком, чем скакать туда-сюда по индексу.
И он тут прав.
Индексы хороши там, где значение отсекает много строк, а не половину.

6. SELECT * мешает covering index 📦 Иногда индекс уже содержит все поля, которые тебе нужны, и база может отдать ответ прямо из него, не заглядывая в таблицу.
Красота. Но стоит написать SELECT * — и она вынуждена лезть в таблицу за каждой строкой ради остальных колонок. Бери только то, что реально используешь.

В общем, индекс — это не «создал и забыл».
Прежде чем гадать на кофейной гуще, открой EXPLAIN ANALYZE и посмотри, что там планировщик на самом деле делает.
Он-то не соврёт.

А у вас какой случай в духе «индекс есть, но его как бы нет» бесил сильнее всего? 🤔

#sql #database #postgres #backend #performance #dev
More from @evapps_team
  1. Sep 21, 2026🧩 Что тут не так? Код-загадка Формат новый - показываю код, ты угадываешь подвох, ниже ра…
  2. Sep 18, 2026🎭 Мифы про производительность, в которые верят даже опытные Миф 1: "Меньше строк кода - б…
  3. Sep 16, 2026🚨 Как перевод денег уронил нам прод ⏰ 19:10 Задеплоили долгожданное - переводы между коше…
  4. Sep 14, 2026🗃 Кэш поставили, а он отдаёт старьё В программировании две сложные вещи - инвалидация кэш…
  5. Sep 11, 2026🔌 "Too many connections" - и почему база падает под нагрузкой Под нагрузкой прилетает FAT…
  6. Sep 11, 2026Пока вы наслаждаетесь пятницей, мы напоминаем, что уже завтра стартует одна из наших любим…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →