PostgreSQL для новичков: как я подружился с индексами и EXPLAIN

Grigory.Novikov

New member
Всем привет! Я разработчик, и недавно мне пришлось плотно столкнуться с PostgreSQL. Сначала я думал, что индексы — это просто «поставил и забыл», а EXPLAIN — что-то для гуру. Но когда база начала тормозить на реальных данных, пришлось разбираться. Делюсь своим опытом и кейсами, которые помогли мне понять оптимизацию запросов.

Индексы в PostgreSQL — это не серебряная пуля. Я начинал с обычного B-tree, потому что он подходит для большинства запросов с фильтрацией и сортировкой. Но когда появились полнотекстовый поиск и JSONB, я узнал про GIN и GiST. Главное правило: индекс ускоряет чтение, но замедляет запись. Я наступил на грабли, создав индексы на все поля подряд — вставки стали медленными, а планировщик иногда их игнорировал.

EXPLAIN стал моим лучшим другом. Сначала я смотрел только на стоимость, но потом понял, что важнее EXPLAIN ANALYZE, который реально выполняет запрос. Я научился отличать Seq Scan от Index Scan и видеть, где планировщик ошибается. Например, если вижу Seq Scan на большой таблице с условием WHERE, это намёк, что индекса не хватает или он не подходит.

Кейс первый. У меня была таблица заказов на 5 миллионов строк. Запрос с фильтром по статусу и дате выполнялся 3 секунды. Я добавил составной индекс по (status, created_at), и время упало до 50 мс. Но сначала я сделал индекс только по status — эффект был слабым. Составной индекс с правильным порядком колонок решил проблему. EXPLAIN показал Index Scan вместо Seq Scan.

Кейс второй. Джойн двух больших таблиц внезапно стал медленным. Я запустил EXPLAIN ANALYZE и увидел Hash Join с огромным количеством строк. Оказалось, что не было индекса на внешнем ключе. После создания индекса на колонку в дочерней таблице планировщик переключился на Nested Loop с индексным сканированием. Это ускорило запрос в 20 раз. Ещё я узнал про покрывающие индексы — когда все нужные колонки уже в индексе, PostgreSQL не идёт в таблицу.

Что советую новичкам? Не бойтесь EXPLAIN, это не страшно. Начните с EXPLAIN ANALYZE на медленных запросах. Следите за pg_stat_statements — он покажет самые ресурсоёмкие запросы. Не создавайте индексы «на всякий случай». И помните: оптимизация — это итеративный процесс. Иногда достаточно переписать запрос, а не добавлять индекс.

В итоге, PostgreSQL даёт мощные инструменты, но они требуют практики. Я до сих пор учусь, и каждый раз EXPLAIN открывает что-то новое. А как вы оптимизируете запросы? Был ли у вас опыт, когда один индекс кардинально менял производительность? Поделитесь в комментариях, интересно почитать!
 
О, классная тема! Я тоже поначалу думал, что индексы — это просто «добавить везде и будет быстро». Потом наткнулся на EXPLAIN ANALYZE и понял, что без него можно легко сделать хуже: лишние индексы тормозят вставку и обновление, а планировщик иногда всё равно выбирает Seq Scan. Сейчас стараюсь сначала смотреть план запроса, а уже потом решать, какой индекс нужен.

А у тебя не было такого, что после добавления индекса запрос вдруг становился медленнее? Или как ты понимаешь, когда пора переходить от EXPLAIN к EXPLAIN ANALYZE? Заранее спасибо за опыт!
 
Спасибо за тему, очень откликается! Я тоже начинал с паники от слова EXPLAIN, а потом понял, что это просто разговор с базой, где она честно рассказывает, что собирается делать. Самое полезное для меня было перестать гадать и смотреть EXPLAIN ANALYZE на реальных запросах — сразу видно, где Seq Scan на маленькой таблице нормален, а где индекс реально спасает.

Но у меня до сих пор вопрос: как вы решаете, когда индекс уже лишний? Я наделал их пачку, а на INSERT стало заметно медленнее, и теперь думаю, как искать неиспользуемые. И ещё: часто ли у вас планировщик игнорирует индекс из-за низкой селективности, и что вы с этим делаете?
 
Назад
Вверх