@Tregoreg在评论中提出了一个问题:
我没有发现目前的答案工作。使用GIN指数
数组类型的列不会提高ANY()的性能。
操作符。真的没有解决办法吗?
@Frank接受的答案告诉您使用数组操作符,这对于Postgres 11仍然是正确的。手册:
... PostgreSQL的标准发行版包含一个GIN操作符
类,它支持使用这些对象进行索引查询
运营商:
< @
@ >
=
& &
这里是标准发行版中GIN索引的内置操作符类的完整列表。
在Postgres中,索引绑定到操作符(为某些类型实现),而不仅仅是数据类型或函数或其他任何东西。这是Postgres最初的伯克利设计的遗产,现在很难改变。而且总体来说还不错。这里有一个关于pgsql-bugs的帖子,Tom Lane对此进行了评论。
一些PostGis函数(如ST_DWithin())似乎违反了这个原则,但事实并非如此。这些函数在内部被重写以使用各自的操作符。
The indexed expression must be to the left of the operator. For most operators (including all of the above) the query planner can achieve this by flipping operands if you place the indexed expression to the right - given that a COMMUTATOR has been defined. The ANY construct can be used in combination with various operators and is not an operator itself. When used as constant = ANY (array_expression) only indexes supporting the = operator on array elements would qualify and we would need a commutator for = ANY(). GIN indexes are out.
Postgres目前还没有聪明到可以从中派生一个GIN-indexable表达式。对于初学者来说,constant = ANY (array_expression)并不完全等同于array_expression @> ARRAY[constant]。如果数组操作符中包含任何NULL元素,则返回一个错误,而any构造可以处理任意一侧的NULL。对于数据类型不匹配有不同的结果。
相关的答案:
检查Postgres数组中是否存在值
用于在JSON数组中查找元素的索引
如何过滤PgArray列类型?
IS能以某种方式与ANY或ALL结合吗?
旁白
在使用没有NULL值的整数数组(int4,而不是int2或int8)时(就像您的例子所暗示的那样),考虑额外的模块intarray,它提供了专门的、更快的操作符和索引支持。看到的:
如何在PostgreSQL中为数组元素创建索引?
比较数组是否相等,忽略元素的顺序
至于你的问题中没有得到回答的UNIQUE约束:它是在整个数组值上使用btree索引实现的(就像你怀疑的那样),根本无助于搜索元素。细节:
PostgreSQL如何强制UNIQUE约束/它使用什么类型的索引?