B-tree индекс

Тема дорожной карты · PostgreSQL

Индекс B-tree является стандартным и наиболее универсальным типом индекса в PostgreSQL: он выбирается автоматически при выполнении CREATE INDEX без указания метода. Индекс B-tree организует значения в виде сбалансированного дерева, поддерживающего запросы на равенство и диапазон (=, <, >, BETWEEN, LIKE 'prefix%'), что делает его основным инструментом оптимизации запросов в любой реляционной базе данных PostgreSQL. PostgreSQL автоматически использует индексы B-tree для операций ORDER BY, GROUP BY и DISTINCT, когда индекс покрывает сортируемый столбец, что нередко устраняет дорогостоящие шаги сортировки из плана запроса, видимого в EXPLAIN ANALYZE. Составные индексы B-tree — создаваемые командой CREATE INDEX ON orders (customer_id, created_at) — поддерживают многостолбцовую фильтрацию с правилом крайнего левого префикса, а покрывающие индексы с использованием предложения INCLUDE позволяют выполнять запросы целиком из индекса, не обращаясь к основной таблице, что значительно повышает пропускную способность при частых операциях чтения.

Как это работает

B-tree индекс ускоряют чтение ценой записи + 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).

Типичные ошибки

Ловушки B-tree индекс: слишком много индексов (каждый 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 после больших записей — статистика планировщика свежая.

Связанные понятия

Полезные ресурсы