Какие типы индексов существуют в PostgreSQL?

«Какие типы индексов существуют в PostgreSQL?» — вопрос из категории Базы данных, который задают на 22% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

  • B-tree (B-дерево)

    • Для чего подходит: Индекс по умолчанию. Эффективен для широкого спектра операций сравнения: =, >, <, BETWEEN, IN, а также для сортировки (ORDER BY).
    • Пример:
      CREATE INDEX idx_users_email ON users (email);
  • Hash (Хеш-индекс)

    • Для чего подходит: Только для точных совпадений (=). Может быть быстрее B-tree для таких запросов, но не поддерживает диапазоны или сортировку.
    • Пример:
      CREATE INDEX idx_users_phone ON users USING HASH (phone_number);
  • GIN (Generalized Inverted Index)

    • Для чего подходит: Идеален для индексации составных типов, где один элемент может содержать много значений. Например: массивы (text[]), jsonb, полнотекстовый поиск (tsvector).
    • Пример:
      -- Индексация поля tags, которое является массивом
      CREATE INDEX idx_posts_tags ON posts USING GIN (tags);
  • GiST (Generalized Search Tree)

    • Для чего подходит: Используется для индексации сложных структур данных, таких как геометрические данные (PostGIS) и диапазоны.
    • Пример:
      -- Индексация геометрических данных
      CREATE INDEX idx_locations_point ON locations USING GIST (point);
  • BRIN (Block Range Index)

    • Для чего подходит: Очень компактный индекс для больших, естественно отсортированных таблиц (например, по дате создания). Хранит метаданные (min/max) для блоков страниц, а не для каждой строки.
    • Пример:
      CREATE INDEX idx_logs_created_at ON logs USING BRIN (created_at);
  • SP-GiST (Space-Partitioned GiST)

    • Для чего подходит: Для индексации неสมดุลных (non-balanced) структур данных, таких как префиксные деревья (IP-адреса, телефонные номера).
    • Пример:
      CREATE INDEX idx_ip_routes ON routes USING SPGIST (ip_range);