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 должно совпадать с выражением в индексе.