jsonb индекс джина не используется в postgresql - PullRequest
0 голосов
/ 26 февраля 2020

Я создаю следующие индексы для столбцов jsonb в моей таблице:

CREATE INDEX idx_gin_accounts ON t1 USING GIN (accounts jsonb_path_ops);
CREATE INDEX idx_gin_stocks ON t1 USING GIN (stocks jsonb_path_ops);

CREATE INDEX idx_gin_stocks_value ON t1 USING GIN ((stocks-> 'value'));
CREATE INDEX idx_gin_stocks_type ON t1 USING GIN ((stocks-> 'type'));

Мой запрос выглядит так:

SELECT  
    t.accounts ->> 'name'                             as account_name
    //other columns
FROM t1 t
         left join lateral jsonb_array_elements(t.accounts) a(accounts)
                   on 1 = 1 and a.accounts @> '{"role": "ADVISOR"}'
         left join lateral jsonb_array_elements(t1.stocks) s(stocks)
                   on 1 = 1 and s.stocks @> '{"type": "RIC"}'
WHERE (s.stocks -> 'value' ? 'XXX')

Когда я анализирую с помощью EXPLAIN ANALYSE, я не вижу эти индексы используются в плане запроса.

Должны ли быть созданы другие индексы? Или как я могу использовать эти, чтобы ускорить поиск?

Скажи, когда я передам (s.stocks-> 'value' ? 'XXX') в каком-то условии, я бы хотел, чтобы поиск был оптимальным?

1 Ответ

3 голосов
/ 26 февраля 2020

Вы не можете индексировать результаты функции возврата набора (кроме создания материализованного представления).

Мы можем рассуждать, что если a.accounts @> '{"role": "ADVISOR"}', то необходимо t.accounts @> '[{"role": "ADVISOR"}]'. PostgreSQL не может этого объяснить, но мы можем.

Однако это также не поможет, потому что вы делаете левые соединения. Если возвращается каждая строка t1, чего ожидать от индекса sh?

С добавленным предложением WHERE вы можете использовать JSONPATH (если вы используете последнюю версию PostgreSQL ), чтобы получить строки t1, которые вы, кажется, хотите. Он будет использовать индекс для t1 (stocks), с или без jsonb_path_ops:

WHERE (s.stocks -> 'value' ? 'XXX') AND
    t.stocks @? '$[*] ? (@.type == "RIC" ) ? (exists (@.value.XXX))';

Однако индекс не очень эффективен, если почти все записи имеют тип RI C, поэтому это пирри c победа.

...