SQLLab
ИндексыСредний

B-tree индекс

Тип индекса по умолчанию в PostgreSQL. Подходит для операций =, <, >, BETWEEN, LIKE 'prefix%'.

Синтаксис
CREATE INDEX ON table USING btree (column);  -- btree по умолчанию

Объяснение

B-tree (Balanced Tree) — сбалансированное дерево поиска. Поиск за O(log n). Поддерживает: =, <, <=, >, >=, BETWEEN, IN, LIKE 'prefix%', IS NULL (частично). Не подходит: LIKE '%suffix', поиск по массивам, full-text search. Для этих случаев используй: GIN (массивы, JSONB, FTS), GiST (геометрия, диапазоны), pg_trgm+GIN (LIKE '%text%').

Пример

-- B-tree хорош для:
CREATE INDEX ON orders (created_at);  -- диапазон дат
CREATE INDEX ON users (email);         -- точное совпадение

-- GIN для массивов:
CREATE INDEX ON articles USING gin (tags);

Анекдоты по теме

— Почему UUID медленнее INT как первичный ключ? — UUID случайный — вставки разбросаны по всему индексу. — INT последовательный — всегда в конец. — Насколько медленнее? — На больших таблицах B-tree страницы постоянно разбиваются. В разы медленнее INSERT. — Решение? — UUID v7 (упорядоченный по времени) или ULID — случайные, но монотонные.

— Что такое seq_page_cost и random_page_cost? — Параметры PostgreSQL для оценки стоимости I/O. — По умолчанию random_page_cost = 4.0 (в 4 раза дороже seq). — На SSD? — Лучше поставить 1.1–1.5. Оптимизатор будет чаще использовать индексы. — Это действительно меняет планы? — Значительно.

Оптимизатор запросов говорит медленному подзапросу: — Ты почему такой тормоз? Подзапрос (ковыряя IN (SELECT ...)): — Я каждую строчку с каждой сравниваю. Зато честно. Оптимизатор: — Используй EXISTS. Подзапрос, помолчав: — Так я не знаю, существую ли я на самом деле после этого...