【问题标题】:Gin Index not being used when searching in JSONB column (PostgreSQL) with an array of search terms使用搜索词数组在 JSONB 列 (PostgreSQL) 中搜索时未使用 Gin 索引
【发布时间】:2021-05-30 19:05:12
【问题描述】:

我有一个名为 myContent 的 JSONB 列,每行的 JSON 中的一个对象如下所示:

  "metadata": {
    "key": "key",
    "teamBased": false,
  }

我想选择所有 teamBased 为 false 的行。 这是我的查询的样子:

set enable_seqscan=false;
EXPLAIN ANALYZE
SELECT *
FROM table n
WHERE n.key = 'key'
AND myContent @> ALL(array[:searchTerms]::jsonb[]));

我从我的 Java 应用程序中将 searchTerms 作为数组发送,在这种情况下,该数组如下所示:

 ['{"metadata":{"teamBased":false}}']

我创建了一个如下所示的 GIN 索引:

  create index "myIndex"
    on myTable using gin (myContent);

当我查看explain analyze query 的输出时,我发现它没有使用我的索引。但是,如果我将查询更改为此


set enable_seqscan=false;
EXPLAIN ANALYZE
SELECT *
FROM table n
WHERE n.key = 'key'
AND myContent @> '{"metadata":{"teamBased":false}}';

它确实使用了它,所以我假设它与我在原始查询中的搜索词数组存在问题。但是,我真的需要这样的查询,因为这个查询也用于其他情况,当我需要多个搜索词时。

这可能是什么问题?另外,如何修改我的 GIN 索引,使其不设置为整个 JSON,而是设置为其中一个对象,例如 metadata

谢谢!

【问题讨论】:

  • 如果您只有一个元素,我不明白您为什么要使用数组进行比较。
  • @a_horse_with_no_name 在这种特殊情况下,我只有一个元素。在其他情况下,我有不止一个。我在所有情况下都重复使用相同的查询。如果我有多个搜索词,这个索引不应该工作吗?
  • @a_horse_with_no_name 我不确定“该列仅包含一个元素”是什么意思。如果我在问题中添加了一些带有 json 的行,那么查询中的 where 子句将如下所示:@> ALL(array['{"metadata":{"teamBased":false}}', '{"metadata":{"key":"key"}}']::jsonb[]) 并且它工作得很好。它选择所有在其 json 中具有值为“key”且 teamBased 为 false 的键的行。因此,它基本上匹配这两个搜索词。
  • 您是否尝试取消嵌套数组并加入?
  • @clamp 我不确定你的意思。能否提供一段代码?

标签: postgresql jsonb


【解决方案1】:

GIN 索引不支持@> ALL,仅支持@>

The documentation 说:

jsonb 的默认 GIN 运算符类支持使用顶级键存在运算符 ??&?| 运算符和路径/值存在运算符 @> 的查询。

【讨论】:

  • 感谢您的回答!这真的很有帮助。我决定将查询更改为仅使用 @> 并且现在正在使用索引,但是,查询仍然非常慢(大约需要 4 秒,我有大约 20k 行)。我可以做些什么来加快速度吗?
  • 那将是一个不同的问题。确保包含EXPLAIN (ANALYZE, BUFFERS) 输出。
猜你喜欢
  • 2020-06-10
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
  • 2017-04-12
  • 2017-04-23
相关资源
最近更新 更多