您可以在一个函数上创建一个索引,该函数将列的边界作为 int4range 返回:
create or replace function intarray2int4range(arr int[]) returns int4range as $$
select int4range(min(val), max(val) + 1) from unnest(arr) as val;
$$ language sql immutable;
例子:
create table t (a int[]);
insert into t
select array[i - j % 5, i - j % 3, i, i + j % 3, i + j % 5]
from generate_series(0,1000) i, generate_series(0,100) j;
create index on t using gist(a);
vacuum analyze t;
产量:
explain analyze select * from t where 20 <@ intarray2int4range(a) limit 5;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.53..16.55 rows=5 width=41) (actual time=0.056..0.060 rows=5 loops=1)
-> Index Scan using t_intarray2int4range_idx on t (cost=0.53..1669.65 rows=521 width=41) (actual time=0.055..0.058 rows=5 loops=1)
Index Cond: (20 <@ intarray2int4range(a))
Total runtime: 0.095 ms
(4 rows)
它还允许您运行类似的查询来扫描值范围:
explain analyze select * from t where '[20,30]'::int4range && intarray2int4range(a) limit 5;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.53..11.82 rows=5 width=41) (actual time=0.125..0.130 rows=5 loops=1)
-> Index Scan using t_intarray2int4range_idx on t (cost=0.53..3499.66 rows=1550 width=41) (actual time=0.123..0.126 rows=5 loops=1)
Index Cond: ('[20,31)'::int4range && intarray2int4range(a))
Total runtime: 0.169 ms
(4 rows)