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-31-1-operator-classes

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

Найди нужный метод доступа через каталог

«Индекс есть, а не используется» - почти всегда про оператор, а не про индекс. Возьмём JSONB-оператор @>, который btree игнорирует, и через каталог определим, что нужен GIN. Запусти 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

    Создай таблицу с JSONB

    sql
    CREATE TABLE doc (id serial, body jsonb);
    INSERT INTO doc(body)
    SELECT jsonb_build_object('tag', CASE WHEN g%10=0 THEN 'sale' ELSE 'plain' END, 'n', g)
    FROM generate_series(1, 50000) g;
    ANALYZE doc;
    подсказка

    У JSONB-документа много ключей - btree по нему не поможет для содержания.

    ✓ Таблица doc с JSONB готова.

  2. 02

    btree не помогает оператору @>

    sql
    CREATE INDEX doc_btree ON doc (body);
    EXPLAIN SELECT * FROM doc WHERE body @> '{"tag":"sale"}';

    btree на jsonb умеет сравнивать документы целиком, но не оператор содержания @> - план остаётся Seq Scan.

    подсказка

    Оператор @> не входит в operator class btree.

    ✓ Seq Scan - btree бесполезен для @>.

  3. 03

    Спроси каталог, кто знает @>

    sql
    SELECT DISTINCT am.amname
    FROM pg_amop aop
    JOIN pg_operator op ON op.oid = aop.amopopr
    JOIN pg_opfamily f ON f.oid = aop.amopfamily
    JOIN pg_am am ON am.oid = f.opfmethod
    WHERE op.oprname = '@>';

    Предскажи ответ перед запуском: какие методы доступа поддержат @>?

    подсказка

    Ожидается gin и gist - но не btree.

    ✓ Каталог подтвердил: @> поддерживает gin (и gist).

  4. 04

    Создай GIN - оператор оживает

    sql
    CREATE INDEX doc_gin ON doc USING gin (body);
    ANALYZE doc;
    EXPLAIN SELECT * FROM doc WHERE body @> '{"tag":"sale"}';

    Теперь @> в Index Cond, план идёт через GIN (Bitmap Index Scan).

    подсказка

    GIN индексирует ключи и значения JSONB - оператор @> теперь sargable.

    ✓ GIN используется - правильный тип индекса выведен из каталога.

Что ты узнал

Индекс работает для операторов, а не «на колонке»; связь тип+оператор+AM задаёт operator class. Через pg_amop видно, какой метод доступа знает оператор: @> поддерживают gin и gist, но не btree. Поэтому JSONB-поиск по содержанию ускоряет GIN, а btree остаётся Seq Scan.

команды

  • SELECT amname FROM pg_am;методы доступа
  • CREATE INDEX ON t USING gin (jsonb_col);GIN под оператор @>

концепции

  • · operator class связывает тип, оператор и метод доступа
  • · pg_amop показывает, какой AM поддерживает оператор
  • · @> знают gin и gist, но не btree
  • · тип индекса выводится из каталога, а не заучивается

← предыдущая

Расследуй плохой запрос и почини до Index Scan

следующая →

Спустись по B-дереву через pageinspect

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