Кейс: индекс существовал, но Postgres его не использовал
В одном проекте запрос с JOIN по user_id внезапно перешёл с Index Scan на Seq Scan после рефакторинга слоя доступа к данным — без изменений в SQL и без изменений в индексах.
EXPLAIN ANALYZE показал причину: параметр, который раньше передавался как bigint, стал приходить как text из-за смены типа поля в DTO. Planner добавил неявный cast ::text к колонке user_id, чтобы сравнить типы — и индекс на bigint-колонке для сравнения через cast не подошёл.
Исправили тип параметра на bigint на уровне маппинга — Index Scan вернулся без изменений в SQL и без пересборки индекса.
Ловушка в том, что запрос не менялся вообще — ломается совместимость типов на границе ORM. Планировщик молчит, EXPLAIN — единственный способ увидеть implicit cast.
Неявный cast невидим в коде — видим только в плане запроса.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки