PostgreSQL:使用“@?”运算符查询的索引 JSONB 数组
PostgreSQL: Index JSONB array that is queried with `@?` operator
我的 table (table
) 有一个 JSONB 字段 (data
),其中包含一个带有数组的字段,我在其中存储标签 (tags
)。
我用如下表达式查询 table:
SELECT * FROM table WHERE data->'tags' @? '$[*] ? (@ like_regex ".*(foo|bar).*" flag "i");
对于这样的用例,我有没有办法索引 data->'tags'
数组以加快查询速度?或者我应该将 tags
数组移出 JSONB 字段并移入 TEXT[] 字段并对其进行索引?
我已经试过了:
CREATE INDEX foo ON tbl USING GIN ((data->'tags') jsonb_path_ops);
但它不起作用:https://gist.github.com/vkaracic/a62ac917d34eb6e975c4daeefbd316e8
你建立的索引可以使用(如果你设置enable_seqscan=off,你会看到它确实被使用了),但一般不会选择它,因为它对这个查询来说没什么用。它会通过索引排除的唯一行是根本没有 'tags' 键的行,即使这样估计也很差,因此如果不采取严厉措施可能不会使用。
您可以尝试转换为文本 [] 并使用 parray_gin,但可能更好的方法是转换为带有文本的子 table,然后使用 pg_trgm。
我的 table (table
) 有一个 JSONB 字段 (data
),其中包含一个带有数组的字段,我在其中存储标签 (tags
)。
我用如下表达式查询 table:
SELECT * FROM table WHERE data->'tags' @? '$[*] ? (@ like_regex ".*(foo|bar).*" flag "i");
对于这样的用例,我有没有办法索引 data->'tags'
数组以加快查询速度?或者我应该将 tags
数组移出 JSONB 字段并移入 TEXT[] 字段并对其进行索引?
我已经试过了:
CREATE INDEX foo ON tbl USING GIN ((data->'tags') jsonb_path_ops);
但它不起作用:https://gist.github.com/vkaracic/a62ac917d34eb6e975c4daeefbd316e8
你建立的索引可以使用(如果你设置enable_seqscan=off,你会看到它确实被使用了),但一般不会选择它,因为它对这个查询来说没什么用。它会通过索引排除的唯一行是根本没有 'tags' 键的行,即使这样估计也很差,因此如果不采取严厉措施可能不会使用。
您可以尝试转换为文本 [] 并使用 parray_gin,但可能更好的方法是转换为带有文本的子 table,然后使用 pg_trgm。