【问题标题】:Using Postgres 9.5 GIN indexes and JSONB使用 Postgres 9.5 GIN 索引和 JSONB
【发布时间】:2016-01-23 06:20:55
【问题描述】:

我正在尝试创建一个 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 中这样的事情是可能的吗?我也对其他选择持开放态度。不幸的是,我无法规范化表格,所以我需要使用我已经拥有的表格结构。

【问题讨论】:

    标签: sql postgresql gwt-gin jsonb


    【解决方案1】:

    是的,您可以在此处应用 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-function jsonb_array_elements() 放在它所属的FROM 子句中。

    【讨论】:

    • 您好帕特里克,感谢您的回复。但是,我从这种方法中收到两个错误:ERROR: index expression cannot return a setERROR: syntax error at or near "->>" LINE 27: FROM foo, jsonb_array_elements(a)->>'b' AS t(b) -- Implicit ... 我想知道,与使用触发器维护手动索引相比,使用 btree 索引的性能差异是什么?这在未来可能更容易维护和扩展。谢谢!
    • 感谢您的宝贵时间。我最终在另一个线程中找到了答案:stackoverflow.com/questions/26499266/…
    • 我最终使用的查询是SELECT DISTINCT id from foo where a @> '[{"b": "aaa"}]',效率更高一些
    • 只是关于GIN indexes 的注释:有两种类型,此答案中的jsonb_path_ops 是非默认类型。两种索引类型各有优缺点,但jsonb_path_ops 基本上只能与包含运算符(@>)一起使用。
    猜你喜欢
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2020-06-01
    相关资源
    最近更新 更多