具有 jsonb 数据类型列的表
id | json_data(jsonb) |
---|---|
1 | { "CorrelationId": "1111", "参考文献": [ { "Id": "001", "Type": "RefType" }, { "Id": "002", "Type": "RefType" } ] } |
2 | { "CorrelationId": "2222", "参考文献": [ { "Id": "001", "Type": "RefType" }, { "Id": "003", "Type": "RefType" } ] } |
我下面的查询没有使用索引,因此执行速度非常慢:
select * from refs
where json_data -> 'References' @> any(array(select jsonb_build_array(refNo) from jsonb_array_elements(cast('[{"Id":"001","Type":"RefType"},{"Id":"002","Type":"RefType"}]' as jsonb)) refNo))
GIN指数:
CREATE INDEX idx ON refs USING gin ((json_data -> 'References') jsonb_path_ops);
虽然下面的查询执行良好并使用 GIN 索引,但是这个查询有问题,它不会返回第 2 行,所以期望是我希望结果所有行都包含任何/所有匹配的“RefType”,所以在这种情况下,我希望查询返回两者结果中的行虽然第 2 行没有 "Id": "002"
select * from refs
where json_data -> 'References' @> '[{"Id":"001","Type":"RefType"},{"Id":"002","Type":"RefType"}]'
是的,
@> ANY
不会使用GIN索引。
尝试按照以下方式重写查询:
SELECT *
FROM refs
JOIN (SELECT /* whatever you have in the ANY(ARRAY(...)) clause */) AS q(col)
ON json_data -> 'References' @> q.col;
这有可能被处理为嵌套循环连接,并在内侧
refs
上进行索引扫描。