0Pricing
SQL Academy · Урок

Индексация JSONB с помощью GIN

Создавайте индексы GIN для документов JSONB и используйте jsonb_path_ops для быстрых запросов на вхождение

«Индексация JSONB с помощью GIN» — бесплатный урок SQL Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.

Почему для JSONB используется GIN

Документы JSONB содержат множество «элементов» (пар ключ/значение и элементов массивов). GIN (обобщённый инвертированный индекс) предназначен для запросов вида «строки, в которых документ содержит X».

Индекс GIN по умолчанию

Класс операторов по умолчанию поддерживает @>, ?, ?|, ?&:

CREATE INDEX events_data_gin ON events USING GIN (data);

-- These now use the index:
SELECT * FROM events WHERE data @> '{"type":"login"}';
SELECT * FROM events WHERE data ? 'error';

jsonb_path_ops: меньше и быстрее

Вдвое меньше и быстрее для запросов, проверяющих только вхождение, но поддерживает ONLY @>:

CREATE INDEX events_data_gin ON events USING GIN (data jsonb_path_ops);

-- Supports @>
-- Does NOT support ?  ?|  ?&
SELECT * FROM events WHERE data @> '{"type":"login"}';

Индексирование только одного пути

Если вы запрашиваете только один ключ, индекс B-tree по выражению над извлечённым значением будет ещё быстрее:

CREATE INDEX events_user_id_idx
  ON events (((data->>'user_id')::BIGINT));

SELECT * FROM events WHERE (data->>'user_id')::BIGINT = 42;

Индексирование внутри массивов

Используйте индекс GIN для пути к массиву:

CREATE INDEX events_tags_gin
  ON events USING GIN ((data->'tags'));

SELECT * FROM events WHERE data->'tags' @> '["admin"]'::JSONB;

Комбинирование индекса JSONB с другими фильтрами

Составные предикаты могут использовать индекс GIN для части JSONB и другой индекс для условий, не связанных с JSONB:

EXPLAIN ANALYZE
SELECT * FROM events
WHERE data @> '{"type":"login"}'
  AND ts >= NOW() - INTERVAL '7 days';
-- BitmapAnd: GIN index on data, B-tree on ts

Производительность записи GIN

Обновления GIN тяжелее, чем обновления B-tree. Для таблиц с очень большим объёмом записи параметр fastupdate группирует обновления GIN в списке отложенных операций, который очищается с помощью VACUUM.

CREATE INDEX events_data_gin ON events USING GIN (data) WITH (fastupdate = on);

-- Flush manually if needed:
SELECT gin_clean_pending_list('events_data_gin');

Размер индекса

Индексы GIN для JSONB могут быть большими. Для огромных таблиц рассмотрите следующие варианты:

  • Индексирование только определённых путей (индекс по выражению)
  • Переход на jsonb_path_ops для запросов, проверяющих только вхождение
  • Вынесение часто изменяемых полей в обычные столбцы

Комбинирование с триграммами

Для нечёткого текстового поиска внутри JSONB извлеките значение в выражении типа TEXT и добавьте индекс GIN на основе pg_trgm:

CREATE INDEX events_message_trgm
  ON events USING GIN ((data->>'message') gin_trgm_ops);

Когда индексирование не помогает

Если фильтр затрагивает каждую строку (избирательность очень низкая), планировщик может выбрать последовательное сканирование даже при наличии индекса. Выполните EXPLAIN ANALYZE для проверки.

Обслуживание индексов JSONB

Индексы GIN разрастаются так же, как любые другие индексы. Периодически используйте REINDEX CONCURRENTLY:

REINDEX INDEX CONCURRENTLY events_data_gin;

Итоги

GIN превращает фильтрацию JSONB в поиск за миллисекунды.

  • GIN по умолчанию: @>, ?, ?|, ?&
  • jsonb_path_ops: меньше, только для проверки вхождения
  • B-tree по выражению над извлечённым скалярным значением: самый быстрый вариант для одного ключа

Быстрая проверка

Вы всегда выполняете запросы вида data @> ... к столбцу JSONB. Какой индекс будет самым компактным при полной поддержке нужных возможностей?

Часто задаваемые вопросы

Урок «Индексация JSONB с помощью GIN» бесплатный?

Да — полный текст урока «Индексация JSONB с помощью GIN» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.

Чему я научусь в уроке «Индексация JSONB с помощью GIN»?

Создавайте индексы GIN для документов JSONB и используйте jsonb_path_ops для быстрых запросов на вхождение Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Academy?

Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Индексация JSONB с помощью GIN»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Academy?

Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. JSONB и JSON: когда что использовать
  2. Операторы путей: -> ->> @>
  3. Индексация JSONB с помощью GIN
  4. Моделирование: когда JSONB лучше нормализации
← Назад к SQL Academy