我在列agg_series_id
上创建了integer[]
类型,并在其上创建了intarray
索引。查询创建索引是:
CREATE INDEX idx_agg_series_id ON some_tbl USING gin (agg_series_id gin__int_ops);
表格大约是500k行。我有查询SELECT count(*) FROM some_tbl WHERE agg_series_id <@ ARRAY [1]
的执行计划:
Aggregate (cost=129835.91..129835.92 rows=1 width=8)
-> Seq Scan on some_tbl (cost=0.00..129835.89 rows=11 width=0)
Filter: (agg_series_id @> '{1}'::integer[])
从计划中可以看出,没有使用intarray索引。通过设置seqscan
关闭set enable_seqscan=off;
并未更改计划。我尝试增加列的统计信息,并尝试执行VACUUM ANALYZE
。
但是如果我从索引中删除intarray扩展名(gin__int_ops
)然后创建一个新索引:
CREATE INDEX idx_agg_series_id2 ON some_tbl USING gin (agg_series_id);
在这种情况下,新索引用于执行计划:
Aggregate (cost=55.93..55.94 rows=1 width=8)
-> Bitmap Heap Scan on some_tbl (cost=12.08..55.91 rows=11 width=0)
Recheck Cond: (agg_series_id @> '{1}'::integer[])
-> Bitmap Index Scan on idx_agg_series_id2 (cost=0.00..12.08 rows=11 width=0)
Index Cond: (agg_series_id @> '{1}'::integer[])
所以问题是:为什么在integer[]
列的执行计划中没有使用intarray索引,而是使用通常的数组索引?或者我可以调整一些设置或类型,以便可以使用intarray索引?
在x86_64-pc-linux-gnu上的PostgreSQL 9.6.2,由gcc编译(Debian 4.9.2-10)4.9.2,64位
答案 0 :(得分:0)
您是否使用某些架构指定gin__int_ops
选项?因为看起来你已将intarray扩展安装到另一个模式中。您看到intarray扩展程序的<@
运算符(以及&&
,@>
)为equivalent to built-in operators of the same name,因此如果没有安装intarray扩展程序,{{1} }运算符将用作常规数组的运算符。在本回合中,将使用常规GIN索引。
您可以检查您的方案中是否安装了intarray扩展程序。尝试在某个查询中使用icount
函数。如果您收到“未找到”消息的错误,那么您在当前架构中没有intarray扩展名。如果是这样,您可以使用命令<@
更改当前架构。
如果将不同的运算符用于inarray运算而不是内置运算符,可能会减少混淆。