Выбор из поля JSONB медленный - PullRequest
0 голосов
/ 07 сентября 2018

У меня сравнительно небольшая таблица (~ 50 тыс. Строк).Когда я выбираю все записи, это занимает ~ 40 с.Таблица имеет 3 столбца JSONB.Когда я выбираю каждый столбец, кроме JSONB, запрос занимает ~ 700 мс.

Если я добавлю только одно из полей JSONB, время запроса увеличится почти до 10 с.

Яникогда не использовать предложение where, ссылающееся на что-то внутри JSONB, просто выбирая *.Несмотря на это, я попытался добавить индексы GIN, потому что видел, что их часто упоминают как повышение производительности для JSONB.

Я запустил полный вакуум.

Postgres версия 9.6

 explain (analyze, buffers) select * from message;
   Seq Scan on message  (cost=0.00..5541.69 rows=52969 width=834) (actual 
   time=1.736..116.183 rows=52969 loops=1)
     Buffers: shared hit=64 read=4948
   Planning time: 0.151 ms
   Execution time: 133.555 ms

1 Ответ

0 голосов
/ 07 сентября 2018

Jsonb - это тип данных PostgreSQL varlena - это означает, что когда значение превышает 2 КБ, оно сохраняется во вспомогательной таблице (называемой таблицей TOAST). Указатель на таблицу TOAST хранится в основной таблице. Поэтому, когда вы не касаетесь столбца Jsonb, это значение не читается.

Индекс GIN в этом случае не помогает. Это помогает только для поиска.

10 сек. При значениях 50 КБ - это длительное время - возможно, ваши значения Jsonb довольно длинные или ваша система ввода-вывода не работает должным образом. Пожалуйста, проверьте размер таблицы и проверьте производительность своего ввода-вывода. У дешевых облачных машин обычно ужасный IO.

Другая возможная причина замедления - сложность типа данных Jsonb. Jsonb - это сериализованное дерево суб-объектов json. Если вам не нужны какие-то особые функции типа данных Jsonb, используйте тип данных JSON. Это всего лишь тест (формат JSON проверяется только на входе). Вывод JSONB быстрее, чем Jsonb, потому что JSON является внутренним текстом, и никаких операций не требуется. Вывод Jsonb должен быть сериализован, что дороже.

...