简体   繁体   English

jsonb gin 索引未在 postgresql 中使用

[英]jsonb gin index not being used in postgresql

I create the following indexes on jsonb columns in my table:我在表中的 jsonb 列上创建以下索引:

CREATE INDEX idx_gin_accounts ON t1 USING GIN (accounts jsonb_path_ops);
CREATE INDEX idx_gin_stocks ON t1 USING GIN (stocks jsonb_path_ops);

CREATE INDEX idx_gin_stocks_value ON t1 USING GIN ((stocks-> 'value'));
CREATE INDEX idx_gin_stocks_type ON t1 USING GIN ((stocks-> 'type'));

My query is like this:我的查询是这样的:

SELECT  
    t.accounts ->> 'name'                             as account_name
    //other columns
FROM t1 t
         left join lateral jsonb_array_elements(t.accounts) a(accounts)
                   on 1 = 1 and a.accounts @> '{"role": "ADVISOR"}'
         left join lateral jsonb_array_elements(t1.stocks) s(stocks)
                   on 1 = 1 and s.stocks @> '{"type": "RIC"}'
WHERE (s.stocks -> 'value' ? 'XXX')

When I analyse with EXPLAIN ANALYSE I do not see these indexes being used in the query plan.当我使用EXPLAIN ANALYSE进行分析时,我没有看到查询计划中使用了这些索引。

Should different indexes be created?是否应该创建不同的索引? Or How can I use these ones to speed up the search?或者我如何使用这些来加快搜索速度?

Say When I pass in (s.stocks-> 'value' ? 'XXX') in where condition, I would want the search to be optimal?说当我在 where 条件下传入(s.stocks-> 'value' ? 'XXX')时,我希望搜索是最佳的?

You can not index the results of a set returning function (other than making a materialized view).您不能索引集合返回函数的结果(除了创建物化视图)。

We can reason out that if a.accounts @> '{"role": "ADVISOR"}' than it is necessary that t.accounts @> '[{"role": "ADVISOR"}]' .我们可以a.accounts @> '{"role": "ADVISOR"}'出,如果a.accounts @> '{"role": "ADVISOR"}'t.accounts @> '[{"role": "ADVISOR"}]'是必要t.accounts @> '[{"role": "ADVISOR"}]' PostgreSQL can't reason that out, but we can. PostgreSQL 无法解释这一点,但我们可以。

However, this also won't help, because you are doing left joins.但是,这也无济于事,因为您正在执行左连接。 If every single row of t1 is getting returned, what do expect an index to accomplish?如果 t1 的每一行都被返回,那么索引要完成什么?

With your added WHERE clause, you can use a JSONPATH (if you are using the latest version of PostgreSQL) to get the rows of t1 that you seem to want.通过添加 WHERE 子句,您可以使用 JSONPATH(如果您使用的是最新版本的 PostgreSQL)来获取您想要的 t1 行。 It will use the index on t1 (stocks) , either with or without the jsonb_path_ops :它将使用t1 (stocks)上的索引,有或没有jsonb_path_ops

WHERE (s.stocks -> 'value' ? 'XXX') AND
    t.stocks @? '$[*] ? (@.type == "RIC" ) ? (exists (@.value.XXX))';

However, the index is not actually very efficient if almost all entries have a type RIC, so this is pyrrhic victory.但是,如果几乎所有条目都具有 RIC 类型,则索引实际上并不是很有效,因此这是一种得不偿失的胜利。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM