给出一个表
create table tmp (data jsonb not null);
和数据
insert into tmp (data) values ('{"root": [{"name": "item1"}, {"name": "item2"}]}');
我需要索引jsonb列'data'来快速回答像
这样的查询select * from tmp where data->'root' @> '[{"name": "item1"}]';
在Postgres 9.4 +中是否有可能?
答案 0 :(得分:0)
经过一些调试后,我了解到为外部json元素创建的索引(例如“root”)也适用于层次结构中的所有嵌套元素。所以我的案例中的正确解决方案是:
CREATE INDEX idx_tmp_data_root ON tmp USING gin ((data->'root') jsonb_path_ops);
我选择了jsonb_path_ops
索引操作符类,因为它根据需要支持包含查询@>
,并且与默认索引类型相比,可以产生更紧凑和更快的索引。
这是一个完整的演示:
首先,创建一个表并加载数据:
-> SET enable_seqscan = OFF; -- force postgres to use indices if any
-> create temporary table tmp (data jsonb not null);
-> insert into tmp (data) values ('{"root": [{"name": "item1"}, {"name": "item2"}]}');
没有索引的查询:
-> explain select * from tmp where data->'root' @> '[{"name": "item1"}]';
QUERY PLAN
Seq Scan on tmp (cost=10000000000.00..10000000029.65 rows=1 width=32)
Filter: ((data -> 'root'::text) @> '[{"name": "item1"}]'::jsonb)
(2 rows)
使用索引查询:
-> CREATE INDEX idx_tmp_data_root ON tmp USING gin ((data->'root') jsonb_path_ops);
-> explain select * from tmp where data->'root' @> '[{"name": "item1"}]';
QUERY PLAN
Bitmap Heap Scan on tmp (cost=8.00..12.02 rows=1 width=32)
Recheck Cond: ((data -> 'root'::text) @> '[{"name": "item1"}]'::jsonb)
-> Bitmap Index Scan on idx_tmp_data_root (cost=0.00..8.00 rows=1 width=0)
Index Cond: ((data -> 'root'::text) @> '[{"name": "item1"}]'::jsonb)
(4 rows)
-> SET enable_seqscan = ON;