2016-01-23 133 views
0

我試圖創建一個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的可能這樣的事情?我也願意接受其他選擇。不幸的是,我無法規格化表格,所以我需要使用我已有的表格結構。

回答

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-functionjsonb_array_elements()FROM條款,它屬於英寸

+0

嗨帕特里克,感謝您的答覆。不過,我收到兩個錯誤從此方法: '錯誤:索引表達式不能返回set' 和 '錯誤:在或接近語法錯誤「 - >>」 第27行:從富,jsonb_array_elements (a) - >>'b'AS t(b) - 隱式...' 我想知道,與使用觸發器維護手動索引相比,使用btree索引的性能差異是什麼?未來可能更容易維護和擴展。謝謝! – RandomBK

+0

感謝您的時間。我結束了在另一個線程中找到答案:http://stackoverflow.com/questions/26499266/whats-the-proper-index-for-querying-structures-in-arrays-in-postgres-jsonb?rq=1 – RandomBK

+0

答案已更新。 – Patrick