PostgreSQL: как придумать индекс под медленный запрос
Классическая ситуация: прод тормозит, EXPLAIN показывает Seq Scan на таблице в десятки миллионов строк. Разбираем методику, по которой можно за пятнадцать минут придумать правильный индекс, а не просто вешать индексы на все колонки подряд.
Шаг первый — честно прочитать план. Смотрите не на rows, а на actual time и количество циклов. Часто виноват не сам скан, а сортировка или хеш-джойн, которым не хватило work_mem.
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE user_id = 42 AND status = 'paid' ORDER BY created_at DESC LIMIT 20;
Шаг второй — составной индекс строится по правилу равенства, затем диапазон, затем сортировка. Для запроса выше идеалом будет (user_id, status, created_at DESC): первые две колонки работают фильтром, третья отдаёт данные уже отсортированными — Sort-узел исчезает из плана.
Проверяйте, что индекс реально используют
После создания индекса не забудьте ANALYZE таблицы и убедитесь через pg_stat_user_indexes, что счётчик idx_scan растёт. Мёртвые индекси только замедляют запись, поэтому раз в квартал полезно проводить ревизию.