里使用Postgres 9.5 GIN索引和JSONB
问题描述:
我试图创建一个Postgres GIN索引来加速下面的查询:里使用Postgres 9.5 GIN索引和JSONB
CREATE TABLE foo (
id serial primary key,
a jsonb not null
);
insert into foo(a) values
('[{"b": "aaa"}, {"b": "ddd"}]'::jsonb),
('[{"b": "aaa"}, {"b": "aaa"}]'::jsonb),
('[{"b": "aaa"}]'::jsonb),
('[{"b": "aaa"}]'::jsonb),
('[{"b": "aaa"}]'::jsonb),
('[{"b": "bbb"}]'::jsonb),
('[{"b": "bbb"}]'::jsonb),
('[{"b": "bbb"}]'::jsonb),
('[{"b": "ccc"}]'::jsonb),
('[]'::jsonb);
select distinct id from (
select id, jsonb_array_elements(a)->>'b' as b from foo
) t where t.b = 'aaa'
是在Postgres的可能这样的事情?我也愿意接受其他选择。不幸的是,我无法规格化表格,所以我需要使用我已有的表格结构。
答
是的,你可以在这里申请一个GIN索引,但它可能不是特别有用:
CREATE INDEX find_fast_jsonb_value
ON foo USING GIN (a jsonb_path_ops);
现在你仍然必须通过阵列匹配键/值对进行搜索。您的查询就变成了:
SELECT DISTINCT id
FROM foo, jsonb_array_elements(a) AS t(b) -- Implicit LATERAL join
WHERE b @> '{"b": "aaa"}'; -- Comparing json key/values here
这也放置set-returning-functionjsonb_array_elements()
的FROM
条款,它属于英寸
嗨帕特里克,感谢您的答复。不过,我收到两个错误从此方法: '错误:索引表达式不能返回set' 和 '错误:在或接近语法错误“ - >>” 第27行:从富,jsonb_array_elements (a) - >>'b'AS t(b) - 隐式...' 我想知道,与使用触发器维护手动索引相比,使用btree索引的性能差异是什么?未来可能更容易维护和扩展。谢谢! – RandomBK
感谢您的时间。我结束了在另一个线程中找到答案:http://stackoverflow.com/questions/26499266/whats-the-proper-index-for-querying-structures-in-arrays-in-postgres-jsonb?rq=1 – RandomBK
答案已更新。 – Patrick