@Tregoreg поставив запитання в коментарі до запропонованої йому винагороди:
Я не знайшов діючих відповідей. Використання індексу GIN на стовпчику масиву не збільшує продуктивність оператора ANY (). Невже немає рішення?
@ Прийнята відповідь Франка говорить про використання операторів масиву , що все ще правильно для Postgres 11. Посібник:
... стандартний розподіл PostgreSQL включає клас операторів GIN для масивів, який підтримує індексовані запити за допомогою цих операторів:
<@
@>
=
&&
Повний список вбудованих операторських класів для GIN-індексів у стандартній дистрибуції тут.
У Postgres індекси пов'язані з операторами (які реалізовані для певних типів), а не типами даних або функціями чи чим-небудь іншим. Це спадщина оригінального дизайну Bergley 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 з будь-якої сторони. І є різні результати для невідповідностей типів даних.
Відповідні відповіді:
Убік
Працюючи з integer
масивами ( int4
не int2
або int8
) без NULL
значень (як випливає з вашого прикладу), врахуйте додатковий модуль intarray
, який забезпечує спеціалізовані, швидші оператори та підтримку індексів. Побачити:
Що стосується UNIQUE
обмеження у вашому запитанні, яке не залишилося без відповіді: це реалізовано з btree індексом для всього значення масиву (як ви підозрювали) і зовсім не допомагає шукати елементи . Деталі:
jsonb
та використовувати індекси? postgresql.org/docs/9.5/static/functions-json.html та postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXING