@ Трегорег поднял вопрос в комментарии к предложенной награде:
Я не нашел, что текущие ответы работают. Использование индекса GIN на
столбец с типом массива не увеличивает производительность ANY ()
оператор. Неужели нет решения?
@ Фрэнк принял ответ говорит вам использовать операторы массива , что все еще корректно для Postgres 11. Инструкция:
... стандартный дистрибутив PostgreSQL включает в себя оператор GIN
класс для массивов, который поддерживает индексированные запросы с использованием этих
Операторы:
<@
@>
=
&&
Полный список встроенных классов операторов для индексов GIN в стандартном выпуске приведен здесь.
В Postgres индексы связаны с операторами (которые реализованы для определенных типов), а не только с типами данных или функциями или чем-то еще. Это наследие от оригинального дизайна Postgres в Беркли, и его очень трудно изменить сейчас. И это вообще работает просто отлично. Вот ветка о pgsql-ошибках, которую комментирует Том Лейн.
Некоторые функции PostGis (например, ST_DWithin()
), похоже, нарушают этот принцип, но это не так. Эти функции переписаны для использования соответствующими операторами .
Индексированное выражение должно быть слева от оператора. Для большинства операторов (, включая все вышеперечисленные ) планировщик запросов может достичь этого путем переключения операндов, если поместить индексированное выражение вправо - учитывая, что было определено COMMUTATOR
, Конструкция ANY
может использоваться в сочетании с различными операторами и не является самим оператором. При использовании в качестве constant = ANY (array_expression)
будут учитываться только индексы, поддерживающие оператор =
для элементов массива , и нам потребуется коммутатор для = ANY()
. Индексы GIN отсутствуют.
Postgres в настоящее время недостаточно умен, чтобы извлечь из него индексируемое GIN-выражение. Для начала, constant = ANY (array_expression)
является не полностью эквивалентным до array_expression @> ARRAY[constant]
. Операторы массива возвращают ошибку, если задействованы какие-либо элементы NULL , а конструкция ANY
может работать с NULL с любой стороны. И есть разные результаты для несоответствия типов данных.
Ответы по теме:
Asides
При работе с integer
массивами (int4
, а не int2
или int8
) без значений NULL
(как предполагает ваш пример) рассмотрим дополнительный модуль intarray
, который предоставляет специализированные, более быстрые операторы и поддержку индекса. См:
Что касается ограничения UNIQUE
в вашем вопросе, которое осталось без ответа: оно реализовано с помощью индекса btree для значения весь массив (как вы и предполагали) и не помогает при поиске элементы на всех. Подробности: