注意:我听说过关于正常形式,数据规范化等问题,但这只是理论问题,只是为了学习。
好的,有一些游乐场:
--drop table if exists t;
create table t(i bigserial, x int[]);
insert into t(x)
select
array[(random()*100)::int,(random()*100)::int,(random()*100)::int]
from generate_series(1,100000);
create index idx_t_x on t using gin(x);
analyze t;
索引与数组运算符完美配合,如:
nd@postgres=# explain analyse select * from t where array[5] <@ x;
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ QUERY PLAN ║
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ Bitmap Heap Scan on t (cost=33.88..1004.17 rows=2823 width=41) (actual time=2.453..6.724 rows=2830 loops=1) ║
║ Recheck Cond: ('{5}'::integer[] <@ x) ║
║ Heap Blocks: exact=881 ║
║ -> Bitmap Index Scan on idx_t_x (cost=0.00..33.17 rows=2823 width=0) (actual time=2.205..2.205 rows=2830 loops=1) ║
║ Index Cond: ('{5}'::integer[] <@ x) ║
║ Planning time: 2.501 ms ║
║ Execution time: 7.616 ms ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
但我对any
或all
条件感兴趣,例如constant = any(field)
或constant < all(field)
等等:
nd@postgres=# explain analyse select * from t where 5 > any(x);
╔════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ QUERY PLAN ║
╠════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ Seq Scan on t (cost=0.00..3185.00 rows=98266 width=41) (actual time=0.044..61.822 rows=12961 loops=1) ║
║ Filter: (5 > ANY (x)) ║
║ Rows Removed by Filter: 87039 ║
║ Planning time: 0.186 ms ║
║ Execution time: 64.543 ms ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════╝
有没有办法为这些查询创建有用的索引?
我从this answer获得了一些信息,但可能会从2015年发生变化?
在我老式的视线上,处理像
这样的索引并不算太难 -v1
/
row--v2
\ ...
-vn
所以应该有一些简单而明显的解决方案。