linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/lessons/pg-lab-34-1-gist-spgist

lesson ── postgres-labs ── ~22 мин ── 4 шагов

Запрети пересечения через GiST exclusion constraint

GiST понимает «пересекается», чего B-tree не умеет. Построим запрет двойного бронирования через exclusion constraint и увидим, как GiST ускоряет поиск по пересечению диапазонов. Запусти psql во вкладке client.

▶ интерактивный sandbox

Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.

запустить sandbox →

stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Создай таблицу с запретом пересечений

    sql
    CREATE TABLE room_booking (
      room int,
      during tstzrange,
      EXCLUDE USING gist (room WITH =, during WITH &&)
    );

    Читается: не должно быть двух строк с одинаковой комнатой и пересекающимися интервалами.

    подсказка

    EXCLUDE USING gist опирается на GiST, потому что нужен оператор &&.

    ✓ Exclusion constraint создан.

  2. 02

    Вставь брони и поймай конфликт

    sql
    INSERT INTO room_booking VALUES
      (1, '[2026-01-01 10:00, 2026-01-01 12:00)'),
      (1, '[2026-01-01 12:00, 2026-01-01 14:00)');
    -- эта пересекается с первой - предскажи результат:
    INSERT INTO room_booking VALUES
      (1, '[2026-01-01 11:00, 2026-01-01 13:00)');

    Вторая вставка падает с conflicting key (exclusion). В таблице остаются только две непересекающиеся брони.

    подсказка

    Интервалы [10:00,12:00) и [11:00,13:00) пересекаются - GiST это ловит.

    ✓ Пересекающаяся бронь отклонена - в таблице ровно две строки.

  3. 03

    Построй GiST по диапазону

    sql
    CREATE TABLE cal AS
      SELECT g id, tstzrange(now() + (g || ' hours')::interval,
                             now() + ((g+1) || ' hours')::interval) during
      FROM generate_series(1, 50000) g;
    CREATE INDEX cal_gist ON cal USING gist (during);
    ANALYZE cal;
    подсказка

    GiST хранит охватывающий интервал поддерева - спуск идёт по пересечению.

    ✓ GiST-индекс по диапазону готов.

  4. 04

    Поиск по пересечению через GiST

    sql
    EXPLAIN SELECT * FROM cal
    WHERE during && tstzrange(now() + interval '100 hours', now() + interval '101 hours');

    Узкий интервал пересекает мало строк - GiST отсекает остальные ветви, план идёт по индексу (с Recheck Cond, GiST неточен).

    подсказка

    Оператор && поддерживает только GiST, не B-tree.

    ✓ GiST ускорил поиск по пересечению диапазонов.

Что ты узнал

GiST - дерево для пересечений, содержания и расстояний (&&, @>, <->), чего B-tree не умеет. Exclusion constraint (EXCLUDE USING gist) декларативно запрещает пересечения - например, двойное бронирование. GiST обычно lossy: после индексного отбора идёт Recheck Cond.

команды

  • EXCLUDE USING gist (a WITH =, r WITH &&)запрет пересечений диапазонов
  • CREATE INDEX ON t USING gist (range_col);GiST для поиска по && и @>

концепции

  • · GiST понимает пересечение, содержание, расстояние
  • · exclusion constraint запрещает пересекающиеся значения
  • · GiST lossy - после отбора нужен Recheck Cond
  • · SP-GiST делит пространство на непересекающиеся части

← предыдущая

Сравни hash и B-tree на равенстве

следующая →

btree проваливается на LIKE, GIN спасает полнотекст

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки