为带有嵌套数组的 jsonb 添加和使用索引
Add and use index for jsonb with nested arrays
在我的 PostgreSQL 11.11 中,我有一个 jsonb
列包含这样的对象:
{
"dynamicFields":[
{
"name":"200",
"hidden":false,
"subfields":[
{
"name":"a",
"value":"Subfield a"
},
{
"name":"b",
"value":"Subfield b"
}
]
}
]
}
dynamicFields
是一个数组,subfields
也是一个数组,我在按这样的选择时遇到性能问题:
select *
from my_table a
cross join lateral jsonb_array_elements(jsonb_column -> 'dynamicFields') df
cross join lateral jsonb_array_elements(df -> 'subfields') sf
where df ->> 'name' = '200' and sf ->> 'name' = 'a'
性能问题主要存在于 subfield
。我已经添加了这样的索引:
CREATE INDEX idx_my_index ON my_table USING gin ((marc->'dynamicFields') jsonb_path_ops);
如何在 dynamicFields
中为 subfields
添加索引?
上面的查询只是一个例子,我经常用它来连接数据库中的其他表。我也知道 @>
运算符。
索引用于增强 table 上的查询性能。索引只能在 table 列上完成,并考虑将在 table 连接和 where 子句中使用的那些列使索引变得重要。对于 jsonb 列,您可以使用 gin(column_name, jsonb_path_ops).
在 table_name 上创建索引
您已经有一个很好的索引来支持您的查询。
将它与 jsonb
"contains" operator" @>
:
一起使用
SELECT *
FROM my_table
WHERE marc->'dynamicFields' @> '[{"name": "200", "subfields":[{"name": "a"}]}]';
db<>fiddle here
仔细匹配table中JSON对象的结构。然后使用索引廉价地选择行。
然后,您可以从符合条件的行中提取所需的任何部分。
详细说明:
- Index for finding an element in a JSON array
如果其中一个过滤器本身非常有选择性,那么像您原来的那样拆分这两个条件可能会更快。无论哪种方式,两种变体都应该是 fast:
SELECT *
FROM my_table
WHERE marc->'dynamicFields' @> '[{"name": "200"}]'
AND marc->'dynamicFields' @> '[{"subfields":[{"name": "a"}]}]';
在我的 PostgreSQL 11.11 中,我有一个 jsonb
列包含这样的对象:
{
"dynamicFields":[
{
"name":"200",
"hidden":false,
"subfields":[
{
"name":"a",
"value":"Subfield a"
},
{
"name":"b",
"value":"Subfield b"
}
]
}
]
}
dynamicFields
是一个数组,subfields
也是一个数组,我在按这样的选择时遇到性能问题:
select *
from my_table a
cross join lateral jsonb_array_elements(jsonb_column -> 'dynamicFields') df
cross join lateral jsonb_array_elements(df -> 'subfields') sf
where df ->> 'name' = '200' and sf ->> 'name' = 'a'
性能问题主要存在于 subfield
。我已经添加了这样的索引:
CREATE INDEX idx_my_index ON my_table USING gin ((marc->'dynamicFields') jsonb_path_ops);
如何在 dynamicFields
中为 subfields
添加索引?
上面的查询只是一个例子,我经常用它来连接数据库中的其他表。我也知道 @>
运算符。
索引用于增强 table 上的查询性能。索引只能在 table 列上完成,并考虑将在 table 连接和 where 子句中使用的那些列使索引变得重要。对于 jsonb 列,您可以使用 gin(column_name, jsonb_path_ops).
在 table_name 上创建索引您已经有一个很好的索引来支持您的查询。
将它与 jsonb
"contains" operator" @>
:
SELECT *
FROM my_table
WHERE marc->'dynamicFields' @> '[{"name": "200", "subfields":[{"name": "a"}]}]';
db<>fiddle here
仔细匹配table中JSON对象的结构。然后使用索引廉价地选择行。
然后,您可以从符合条件的行中提取所需的任何部分。
详细说明:
- Index for finding an element in a JSON array
如果其中一个过滤器本身非常有选择性,那么像您原来的那样拆分这两个条件可能会更快。无论哪种方式,两种变体都应该是 fast:
SELECT *
FROM my_table
WHERE marc->'dynamicFields' @> '[{"name": "200"}]'
AND marc->'dynamicFields' @> '[{"subfields":[{"name": "a"}]}]';