【问题标题】:jsonb gin index not being used in postgresqljsonb gin 索引未在 postgresql 中使用
【发布时间】:2020-06-10 13:38:20
【问题描述】:

我在表中的 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'));

我的查询是这样的:

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')

当我使用EXPLAIN ANALYSE 进行分析时,我没有看到查询计划中使用了这些索引。

应该创建不同的索引吗?或者我怎样才能使用这些来加快搜索速度?

说当我在 where 条件下传入(s.stocks-> 'value' ? 'XXX') 时,我希望搜索是最优的?

【问题讨论】:

  • “说当我传入 (s.stocks-> 'value' ? 'XXX') 在 where 条件下”如果这是你想要做的,那么这就是你的例子应该显示的。
  • 外连接表上的where 子句将外连接重新变为内连接

标签: sql postgresql query-performance jsonb database-indexes


【解决方案1】:

您不能索引集合返回函数的结果(除了制作物化视图)。

我们可以推断如果a.accounts @> '{"role": "ADVISOR"}'t.accounts @> '[{"role": "ADVISOR"}]' 是必要的。 PostgreSQL 无法推理,但我们可以。

但是,这也无济于事,因为您正在执行左连接。如果 t1 的每一行都被返回,索引能完成什么?

通过添加的 WHERE 子句,您可以使用 JSONPATH(如果您使用的是最新版本的 PostgreSQL)来获取您想要的 t1 行。它将使用t1 (stocks) 上的索引,无论是否带有jsonb_path_ops

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

但是,如果几乎所有条目都具有 RIC 类型,则索引实际上并不是很有效,因此这是一个代价高昂的胜利。

【讨论】:

  • 您也可以将WHERE s.stocks @> '{"value": "XXX"}' 与旧的 PostgreSQL 版本一起使用。
  • 但基于它与? 的使用,我认为“XXX”是一个键,而不是一个值。 '{"value": {"XXX":something}}' 你不能在没有指定值的情况下对键使用包含,我可以看到。 (你可以在 JSONPATH 中做,但它似乎没有有效地使用索引。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2022-12-08
相关资源
最近更新 更多