【问题标题】:Postgresql doesn't use GIN index for "?" JSON operatorPostgresql 不使用 GIN 索引来表示“?” JSON 运算符
【发布时间】:2018-11-29 21:48:13
【问题描述】:

由于某种原因,索引不用于“?”运算符。

让我们以https://schinckel.net/2014/05/25/querying-json-in-postgres/ 为例:

  CREATE TABLE json_test (
  id serial primary key,
  data jsonb
  );

  INSERT INTO json_test (data) VALUES 
  ('{}'),
  ('{"a": 1}'),
  ('{"a": 2, "b": ["c", "d"]}'),
  ('{"a": 1, "b": {"c": "d", "e": true}}'),
  ('{"b": 2}');

并创建一个索引。

create index json_test_index on public.json_test using gin (data jsonb_path_ops) tablespace pg_default;

然后看看下面查询的计划:

SELECT * FROM json_test WHERE data ? 'a';

将进行 Seq Scan,而我希望进行索引扫描。有人能告诉我这里出了什么问题吗?

【问题讨论】:

  • 您的表中有多少行?索引不会用于 5 行的表。
  • 好问题!真实世界的数据库包含成千上万个条目,是的,事实证明 Postgresql 在像该示例这样的微小基础上以不同的方式工作(请参阅下面我对 jjanes 的回复)。

标签: postgresql indexing jsonb


【解决方案1】:

来自the docs:“非默认 GIN 运算符类 jsonb_path_ops 仅支持索引 @> 运算符。”它不支持? 运算符。

因此,请改用 jsonb 的默认运算符(称为“jsonb_ops”,如果您想明确说明的话)。

但是如果你的表只有 5 行,它可能无论如何都不会使用索引,除非你通过set enable_seqscan = off 强制它。

【讨论】:

  • 非常感谢!我使用 @> 重写了我的查询,它已经开始使用索引。实际上,对于我的示例查询 SELECT * FROM json_test WHERE data ,我无法这样做? 'a' 因为在 JSON 中似乎不支持通配符,但我的实际查询可以用这种方式重写 SELECT * FROM json_test WHERE data @> '{"b":{}}' what find all "b" contains实例并使用索引。你在尺寸方面是对的。它从不使用示例数据库上的索引,但在我的真实世界中,它有成千上万个条目,它工作得很好。
猜你喜欢
  • 2018-10-23
  • 1970-01-01
  • 2017-07-30
  • 2020-06-10
  • 1970-01-01
  • 2022-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多