Какие типы индексов поддерживает PostgreSQL и для каких сценариев они предназначены?

Ответ

PostgreSQL предоставляет несколько типов индексов, каждый оптимизирован под определённые виды запросов и данных:

Основные типы:

  1. B-tree (дерево) — стандартный индекс для большинства операций.

    • Для: равенства (=), диапазонов (<, >, BETWEEN), сортировки (ORDER BY), LIKE 'pattern%'.
    • Пример:
      CREATE INDEX idx_users_email ON users(email);
  2. Hash (хэш) — быстрый поиск строгого равенства.

    • Для: только операций = (не поддерживает диапазоны или сортировку).
    • Пример:
      CREATE INDEX idx_users_id_hash ON users USING HASH(id);
  3. GIN (Generalized Inverted Index) — для индексирования составных значений.

    • Для: полнотекстового поиска, массивов (@>), JSONB (?, @>), hstore.
    • Пример (полнотекстовый поиск):
      CREATE INDEX idx_docs_content ON documents USING GIN(to_tsvector('english', content));
  4. GiST (Generalized Search Tree) — для данных, где расстояние или пересечение имеют значение.

    • Для: геопространственных данных (PostGIS), полнотекстового поиска, диапазонов.
    • Пример (геометрия):
      CREATE INDEX idx_places_geom ON places USING GIST(geom);
  5. SP-GiST (Space-Partitioned GiST) — для неоднородных или иерархических данных.

    • Для: IP-адресов (inet, cidr), геометрических типов, текстовых префиксов.
    • Пример:
      CREATE INDEX idx_net_ip ON network USING SPGiST(ip_range);
  6. BRIN (Block Range INdex) — для очень больших, естественно отсортированных таблиц.

    • Для: временных рядов, логов, где данные физически упорядочены (например, по timestamp).
    • Пример:
      CREATE INDEX idx_sensor_brin ON sensor_data USING BRIN(created_at);

Ключевой выбор:

  • B-tree — универсальный выбор для большинства столбцов.
  • GIN/GiST — для сложных типов данных (JSON, массивы, текст, геоданные).
  • BRIN — для огромных таблиц с низкой избирательностью запросов, где важен размер индекса.

Ответ 18+ 🔞

А, ну так, слушай, про индексы в постгресе, да? Ну это же, блядь, целый зоопарк, а не просто какая-то хуйня! Каждый — как инструмент в мастерской: одним гвоздь забить, другим — болт открутить. Сунешь не тот — сам себе еблан и запрос тормозит, как черепаха в патруле.

Вот смотри, какие у нас тут звери водятся, чтобы не облажаться:

Главные персонажи, так сказать:

  1. B-tree (дерево, блядь) — это наш дежурный по кухне, универсальный солдат. Его везде суют по дефолту, и не зря, ёпта.

    • Зачем: когда ищешь ровно что-то (=), или по диапазону (>, <), или сортируешь, или ищешь по началу строки (LIKE 'Вася%').
    • Как наколдовать:
      CREATE INDEX idx_users_email ON users(email);

      Короче, если не знаешь, что хуйню выбрать — бери B-tree, не прогадаешь.

  2. Hash (хэш, ебать) — спринтер, но одноногий. Быстрый, но тупой как пробка.

    • Зачем: ТОЛЬКО для поиска точного совпадения, строгого равенства (=). Диапазоны? Сортировка? Пошёл нахуй, не умею.
    • Как наколдовать:
      CREATE INDEX idx_users_id_hash ON users USING HASH(id);

      Используй, только если на 100% уверен, что будешь искать только по =, а то потом волосы на жопе рвать будешь.

  3. GIN (Generalized Inverted Index) — это наш специалист по бардаку. Любит, когда в одном поле куча всего намешано.

    • Зачем: для полнотекстового поиска (чтобы искать не просто слова, а смыслы, блядь), для массивов, для JSONB (этого, блядь, монстра), для hstore.
    • Пример (ищем по тексту умно):
      CREATE INDEX idx_docs_content ON documents USING GIN(to_tsvector('english', content));

      Если у тебя в поле не одно значение, а целый салат — это твой клиент.

  4. GiST (Generalized Search Tree) — географ и топограф. Для данных, где важно "где" и "рядом ли".

    • Зачем: для геоданных (с PostGIS), опять же для полнотекста, для диапазонов.
    • Пример (ищем ближайший бар):
      CREATE INDEX idx_places_geom ON places USING GIST(geom);

      Короче, если работаешь с картами или чем-то пространственным — GiST тебе в руки, в рот меня чих-пых!

  5. SP-GiST (Space-Partitioned GiST) — младший, но хитрожопый брат GiST. Для данных, которые в обычное дерево не впихнёшь.

    • Зачем: для IP-адресов, для некоторых гео-типов, для текста по префиксам.
    • Пример:
      CREATE INDEX idx_net_ip ON network USING SPGiST(ip_range);

      Штука узкоспециальная, но когда нужно — просто охуенно полезная.

  6. BRIN (Block Range INdex) — индекс для ленивых и для очень-очень больших таблиц. Маленький, но удаленький.

    • Зачем: для ТАБЛИЩ, которые упорядочены от природы. Например, логи по времени или данные с датчиков, которые пишутся подряд. Он не смотрит каждую запись, а целыми блоками, поэтому занимает овердохуища меньше.
    • Пример:
      CREATE INDEX idx_sensor_brin ON sensor_data USING BRIN(created_at);

      Если таблица размером с жизнь и данные в ней лежат последовательно — BRIN спасёт твой диск и, возможно, рассудок.

Итоговая мудрость, чтобы не быть мудаком:

  • B-tree — твой базовый хуй... то есть, инструмент. Не уверен — ставь его.
  • GIN/GiST — когда данные сложные: текст, JSON, гео. Это уже высшая лига.
  • BRIN — когда таблица такая большая, что от одной мысли о B-tree индексе хочется плакать, а данные в ней лежат аккуратно стопочкой.

Выбирай с умом, а то проиндексируешь хуй пойми чем и будешь потом гадать, почему запрос летит не как ракета, а как кирпич.