Частичные индексы
Тема дорожной карты · PostgreSQL
Частичный индекс в PostgreSQL — это индекс, строящийся по подмножеству строк, определяемому предложением WHERE, что позволяет администраторам баз данных создавать небольшие, более эффективные индексные структуры, охватывающие только те данные, которые реально используются в запросах. Поскольку частичный индекс пропускает строки, никогда не встречающиеся в актуальных запросах, он занимает меньше места на диске и обновляется быстрее, чем полнотабличный индекс, — это существенный выигрыш в настройке производительности для таблиц с большим числом неактивных строк или строк со значением NULL. Например, индекс по orders(created_at) WHERE status = 'pending' ускоряет запросы, фильтрующие ожидающие заказы, без индексирования гораздо большего множества завершённых записей. Планировщик запросов PostgreSQL автоматически использует частичный индекс, когда предложение WHERE запроса совпадает или подразумевает предикат индекса, поэтому изменения на стороне приложения не требуются. Частичные индексы — мощный инструмент администрирования баз данных PostgreSQL для повышения производительности SELECT на больших наборах данных с неравномерным распределением.
Как это работает
Частичные индексы ускоряют чтение ценой записи + storage. Типы Postgres: B-tree (дефолт, равенство + диапазон), Hash (только равенство), GIN (full-text, JSONB, containment массивов), GiST (геометрия, full-text), BRIN (огромные таблицы с естественным порядком — time-series), Bloom (multi-column равенство). Partial indexes (WHERE) пропускают нерелевантные строки; expression indexes ((lower(email))) ловят запрос с трансформацией; covering indexes (INCLUDE) избегают heap-lookup (index-only scans).
Когда применять
Индексируйте колонки в WHERE / JOIN / ORDER BY для запросов, которые реально гоняете — никогда "на всякий случай". EXPLAIN (ANALYZE, BUFFERS) — подтвердить, что индекс используется. Для JSONB-запроса по ключу — GIN на поле; для full-text — to_tsvector + GIN. BRIN — для append-only данных с монотонными timestamp: крошечный индекс, огромные таблицы. Удаляйте неиспользуемые индексы (pg_stat_user_indexes: idx_scan = 0).
Типичные ошибки
Ловушки Частичные индексы: слишком много индексов (каждый INSERT/UPDATE переписывает их все — write amplification); функциональные WHERE (WHERE lower(email) = ?) без соответствующего expression-index (full-scan); B-tree на boolean (низкая cardinality, бесполезно — partial index WHERE flag = true правильно); не CREATE INDEX CONCURRENTLY в production (обычный CREATE INDEX лочит записи). Всегда ANALYZE после больших записей — статистика планировщика свежая.