Как ускорить запрос postgres для большой таблицы

У меня есть таблица с ~ 1,4 миллионами строк. Есть около 5 столбцов с общей информацией о каждой строке и 6-й столбец с ~ 1700 парами значений ключа JSON.

Я строю некоторые сводки из столбца, называемого собственностью, выбирая строки, в которых существует определенное значение ключа. Приведенный ниже запрос выполняется за 14,5 с.

SELECT ownership,
SUM (TO_NUMBER(jsonfield->>'firstvalue','9G999g999')) AS total
FROM
mytable
WHERE
jsonfield->>'firstvalue' IS NOT NULL
group by ownership

Мои запросы будут намного больше, и я знаю, что мне нужно будет сделать выбор по многим ключевым значениям из jsonfield. Например, если добавить еще одно значение ключа, время запроса увеличится до 22,9 с.

SELECT ownership,
SUM (TO_NUMBER(jsonfield->>'firstvalue','9G999g999')) AS total,
SUM (TO_NUMBER(jsonfield->>'secondvalue','9G999g999')) AS totaltwo
FROM
mytable
WHERE
jsonfield->>'firstvalue' IS NOT NULL
OR
jsonfield->>'secondvalue' IS NOT NULL
group by ownership

Могут быть случаи, когда мне нужно будет запросить несколько сотен потенциальных значений в поле json. Любые предложения о том, как оптимизировать мои запросы, которые могут ускорить работу?

Отличный ответ ниже. К вашему сведению, мне пришлось преобразовать свой json в jsonb, прежде чем я смог создать индекс. Сначала я создал копию столбца json с именем jsonbsummary, которую затем преобразовал в jsonb.

ALTER TABLE mytable
  ALTER COLUMN jsonbsummary
  SET DATA TYPE jsonb
  USING jsonbsummary::jsonb;

В качестве дополнительной информации: те запросы с группировкой, которые изначально занимали более 22 секунд, теперь выполняются за 200 мс с индексом GIN! Смотри ниже

SELECT ownership,
SUM (TO_NUMBER(jsonbsummary->>'firstvalue','9G999g999')) AS total,
SUM (TO_NUMBER(jsonbsummary->>'secondvalue','9G999g999')) AS totaltwo
FROM
mytable
WHERE
jsonbsummary ?| array['firstvalue','secondvalue']
group by ownership
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
0
163
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужен Индекс ГИН в столбце JSONB.

CREATE INDEX idx_json ON mytable USING GIN (jsoncolumn);

Чтобы проверить наличие ключей, вам нужно использовать ?|оператор, который может использовать этот индекс:

select ...
from mytable
where jsoncolumn ?| array['firstvalue', 'secondvalue'];

Это эквивалентно вашему состоянию OR. Если вы хотите найти строки, содержащие все эти ключи, используйте вместо этого ?&.

Это здорово! Мне пришлось преобразовать мой json в jsonb, прежде чем это запустится. Я добавил эту деталь в свой вопрос

jotamon 01.04.2019 18:11

Другие вопросы по теме