我有一个带有杜松子酒索引的postgres数组列:
CREATE TABLE things (
id integer NOT NULL,
tags character varying(255)[]
);
CREATE INDEX index_things_on_tags ON things USING gin (tags);
有几种方法可以使用各种数组运算符检查列中是否存在元素。以下是我见过的那些:
select * from things where 'blue' = ANY (tags)
select * from things where tags <@ '{"blue"}'
select * from things where '{"blue","yellow"}' && tags;
在postgres 9.3中:
答案 0 :(得分:19)
为什么不测试看?
regress=> SET enable_seqscan = off;
SET
regress=> explain select * from things where 'blue' = ANY (tags);
QUERY PLAN
---------------------------------------------------------------------------
Seq Scan on things (cost=10000000000.00..10000000037.67 rows=6 width=36)
Filter: ('blue'::text = ANY ((tags)::text[]))
(2 rows)
regress=> explain select * from things where tags <@ '{"blue"}';
QUERY PLAN
------------------------------------------------------------------------------------
Bitmap Heap Scan on things (cost=12.05..21.52 rows=6 width=36)
Recheck Cond: (tags <@ '{blue}'::character varying[])
-> Bitmap Index Scan on index_things_on_tags (cost=0.00..12.05 rows=6 width=0)
Index Cond: (tags <@ '{blue}'::character varying[])
(4 rows)
regress=> explain select * from things where '{"blue","yellow"}' && tags;
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on things (cost=12.10..22.78 rows=12 width=36)
Recheck Cond: ('{blue,yellow}'::character varying[] && tags)
-> Bitmap Index Scan on index_things_on_tags (cost=0.00..12.09 rows=12 width=0)
Index Cond: ('{blue,yellow}'::character varying[] && tags)
(4 rows)
因此,Pg正在使用&&
和<@
查询的索引,但不会使用= ANY (...)
。
我确信可以教Pg将x = ANY (y)
转换为ARRAY[x] @> y
,但目前还没有。
2你做的正是你想要的。测试“蓝色”是否是标签之一。这不是一个平等测试,它是一个会员资格测试。