@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