使用 Postgres 9.5 GIN 索引和 JSONB

Using Postgres 9.5 GIN indexes and JSONB

我正在尝试创建一个 Postgres GIN 索引来加速以下查询:

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 中可以实现这样的功能吗?我也对其他选择持开放态度。不幸的是,我无法规范化 table,因此我需要使用已有的 table 结构。

是的,您可以在此处应用 GIN 索引,但它可能不是特别有用:

CREATE INDEX find_fast_jsonb_value
ON foo USING GIN (a jsonb_path_ops);

现在您仍然需要在数组中搜索匹配的 key/value 对。您的查询将变为:

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-function jsonb_array_elements() 放在 FROM 子句中,它所属的位置。