#arrays #postgresql
#массивы #postgresql
Вопрос:
Мне нужно выполнить поиск в большой таблице (более 100 миллионов записей), используя довольно сложный набор правил.
В настоящее время у меня есть таблица, которая выглядит следующим образом
CREATE TABLE equipment (
id serial primary key,
description varchar,
code integer,
tags varchar[]
)
И мне нужно выполнить запрос на основе
1) Определенный список кодов (ГДЕ код В (1,4,5,8)
2) Массив тегов, которых НЕТ в массиве тегов
3) Массив тегов, которые находятся В массиве тегов, но должны присутствовать как минимум два
SELECT * FROM equipment WHERE
code IN (1,3,6,7,8)
AND NOT ('{sports, outdoors, camping}' amp;amp; tags)
AND ('{tennis, squash, badminton, volleyball}' amp;amp; tags)
Но я не знаю, как сделать так, чтобы по крайней мере два значения (теннис, сквош, бадминтон, волейбол) перекрывали массив тегов.
Я использую Postgres 10.6
Ответ №1:
Я думаю, вы можете сделать это, используя только путем удаления тегов и их подсчета:
SELECT e.*
FROM equipment e
WHERE code IN (1,3,6,7,8)
AND NOT ('{sports, outdoors, camping}' amp;amp; tags)
AND EXISTS (SELECT 1
FROM unnest(e.tags) x(tg)
WHERE x.tg = any ('{tennis, squash, badminton, volleyball}')
HAVING count(*) >= 2);
Если у вас есть индекс в tags
столбце, тогда И (‘{теннис, сквош, бадминтон, волейбол}’ amp;amp; теги) сохраняют ваше текущее состояние:
AND ('{tennis, squash, badminton, volleyball}' amp;amp; tags)
может повысить производительность, поскольку это должно предотвратить отмену вложенности тегов для строк, в которых изначально не было найдено совпадений.
Комментарии:
1. Потрясающе, большое спасибо. И да, у меня был индекс GIN в тегах, так что дополнительные И помогли