Gymterview
middle

Как индексировать JSONB-поля?

Для эффективного поиска по JSONB существует три основных подхода: GIN-индекс на всё поле, GIN с классом jsonb_path_ops и B-tree на конкретное выражение. Выбор зависит от паттерна запросов.

GIN-индекс на всё поле (jsonb_ops)

Пример
CREATE INDEX idx_settings_gin ON client_settings USING GIN (settings);

Поддерживает операторы: @>, ?, ?|, ?&. Это наиболее универсальный вариант.

GIN-индекс с классом jsonb_path_ops

Пример
CREATE INDEX idx_settings_path ON client_settings USING GIN (settings jsonb_path_ops);

Поддерживает только оператор @>, но индекс компактнее и быстрее, чем jsonb_ops.

B-tree индекс на конкретное выражение

Пример
-- Если часто ищем по конкретному ключу
CREATE INDEX idx_settings_theme ON client_settings ((settings ->> 'theme'));

-- Использование:
SELECT * FROM client_settings WHERE settings ->> 'theme' = 'dark';

Сравнение подходов

Подход Размер Операторы Когда использовать
GIN jsonb_ops Большой @>, ?, `? , ?&`
GIN jsonb_path_ops Меньше Только @> Поиск по вхождению
B-tree на выражении Маленький =, <, >, LIKE Поиск по конкретному ключу

На собеседовании: покажите понимание компромиссов. GIN jsonb_path_ops — лучший выбор, если нужен только @> (самый частый случай). B-tree на выражении — если поиск всегда по одному и тому же ключу. Не забудьте упомянуть, что ->>-выражение в WHERE должно совпадать с выражением в индексе.