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

Ответ

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);

Ответ 18+ 🔞

А, ну вот, опять про эти ваши индексы, блядь! Сидит человек, думает, что база — это просто табличка, а тут, на тебе, овердохуища разных типов, и каждый со своим характером, как сука в зоопарке. Давайте разберём, пока не начали друг другу в сраку кидаться этими B-деревьями.

B-tree (B-дерево) Это как ваш универсальный солдат, ёпта. Индекс по умолчанию, на все случаи жизни. Нужно найти по равенству, диапазону, отсортировать — он всегда тут как тут, надёжный, как лом. Если сомневаешься, что ставить — ставь его, не прогадаешь, в рот меня чих-пых.

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) Вот это уже мощь, блядь! Создан для хаоса, когда в одной ячейке куча всего намешано. Массивы, JSONB, полнотекстовый поиск — его родная стихия. Представь, у тебя в посте 15 тегов, и нужно найти все посты с тегом "пиздец". GIN разложит это всё по полочкам и найдёт мгновенно.

CREATE INDEX idx_posts_tags ON posts USING GIN (tags);

GiST (Generalized Search Tree) Этот парень — для пространственных извращенцев. Геоданные, диапазоны, всякие сложные структуры — его конёк. Хочешь найти все кафе в радиусе километра? GiST тебе в помощь, он с геометрией на "ты".

CREATE INDEX idx_locations_point ON locations USING GIST (point);

BRIN (Block Range Index) А вот и хитрая жопа! Для таблиц-монстров, которые упорядочены от природы, например, по дате создания логов. Он не парится с каждой строчкой, а хранит инфу целыми блоками (минимум-максимум). Места занимает — как хуй с горы, но на больших данных может выручить, если запросы идут по этим самым диапазонам.

CREATE INDEX idx_logs_created_at ON logs USING BRIN (created_at);

SP-GiST (Space-Partitioned GiST) Ну и на закуску — экзотика. Для данных, которые в B-дерево не впихнёшь, потому что структура у них не сбалансированная. IP-адреса, телефонные номера, всякие префиксные деревья. Штука специфическая, но когда нужно — спасёт твою задницу.

CREATE INDEX idx_ip_routes ON routes USING SPGIST (ip_range);

Вот и весь цирк, блядь. Главное — не тыкать наугад, а подумать, что за данные и какие запросы летать будут. А то накрутишь индексов, а производительность всё равно будет, как у мартышлюшки с калькулятором.