【问题标题】:Indexing a josnb column in postgresql在 postgresql 中索引 jsonb 列
【发布时间】:2020-12-08 21:03:44
【问题描述】:

我在 postgresql 表中有一个类型为 jsonb 的列。

{
    .....
    "type": "car",
     "vehicleIds": [
        "980e3761-935a-4e52-be77-9f9461dec4d1","980e3761-935a-4e52-be77-9f9461dec4d2"
    ]
    .....
}

应用程序对这些字段运行查询以获取记录。我只需要为这些字段索引此列。

如何做到这一点?

这是以属性为列名的查询结构:

SELECT * 
FROM Vehicle f 
WHERE f.properties::text @@ CONCAT('$.vehicleIds[*] >', :vehicleId )= true 
  AND f.properties::text @@ CONCAT('$.type >', :type ) = true

【问题讨论】:

  • 您的查询看起来如何?一般来说,您可以只在整个列上创建一个 gin 索引。如果您使用正确的运算符,则索引可用。
  • 已添加查询的已编辑问题。
  • 嗯,您不能将 @@ 运算符与 text 值一起使用。为什么要将 jsonb 转换为 text
  • 此查询位于我正在处理的遗留项目中,遗憾的是对此并没有太多了解。在负载测试期间,我们发现此查询存在问题,因此正在探索是否可以为此列创建索引。
  • 该查询甚至不应该运行。

标签: postgresql indexing


【解决方案1】:

您使用的查询非常令人困惑,因为它归结为text search 查询,因为@@ 应用于text 值。

我也不明白'$.type > ... 条件。对于像car 这样的值,我希望有一个相等运算符,而不是“大于”。将> 与 UUID 一起使用似乎也没有意义。

如果您想搜索 car 类型的值并且包含 ID 列表,使用“包含”运算符 @> 是一种更好的方法:

SELECT * 
FROM Vehicle f 
WHERE f.properties @> '{"type": "car", "vehicleIds": ["980e3761-935a-4e52-be77-9f9461dec4d1"]}'

上面可以使用properties列上的GIN索引:

create index on vehicles using gin (properties);

如果type 键始终以相等方式查询(我假设),则组合索引可能更有效:

create index on vehicles using gin ( (properties ->> 'type'), (properties -> 'vehicleIds') );

您需要安装 btree_gin 扩展才能创建该索引。

该索引会小一点,但需要不同的查询:

SELECT * 
FROM Vehicle f 
WHERE f.properties ->> 'type' = 'car' 
  AND f.properties -> 'vehicleIds' @> '["980e3761-935a-4e52-be77-9f9461dec4d1"]'

您需要通过查看execution plan 来验证是否使用了索引以及哪些索引更有效

【讨论】:

  • 非常感谢。我会尝试这些建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 2020-09-25
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多