首页 > 解决方案 > where 子句中 jsonb_path_match 和 ->> 之间的性能/逻辑差异是什么

问题描述

我正在尝试在 PostgreSQL 数据库中查询 FHIR 数据。数据存储在 jsonb 字段中。尽管以下查询产生相同的结果,但我想知道在性能或执行计划方面是否存在任何重大差异。

查询 1 - 使用->>运算符

SELECT resource->'subject' FROM resourcetable 
WHERE resource ->> 'resourceType' = 'MedicationRequest' AND resource ->> 'status' = 'active';

查询 2 - 使用 jsonb_path_match 函数

SELECT jsonb_path_query(resource, '$.subject') from resourcetable 
WHERE jsonb_path_match(resource, '$.resourceType == "MedicationRequest"') 
AND jsonb_path_match(resource, '$.status=="active"');

标签: postgresqljsonb

解决方案


你应该在你自己的数据上试试看。如果EXPLAIN在查询文本之前使用,您将获得执行计划。如果您EXPLAIN (ANALYZE, BUFFERS)在查询之前放置,它将实际运行该计划并报告时间和统计信息。

您的第一个公式可能会受益于这样定义的功能索引:

create index on resourcetable ((resource ->> 'resourceType'),(resource ->> 'status'));

您的第二个公式不能从索引中受益,但是如果您将其重写为操作格式:

SELECT jsonb_path_query(resource, '$.subject') from resourcetable 
WHERE resource @@ '$.resourceType == "MedicationRequest"'                       
  AND resource @@ '$.status=="active"';

然后它可以从定义为的索引中受益:

create index on resourcetable using gin (resource jsonb_path_ops);

没有定义的索引jsonb_path_ops也可以使用,但可能效率较低。

您还可以重写条件以使用 JSON_PATH &&,而不是 SQL 的AND.

第二个索引也可以用于使用包含@>而不是 json_path的查询@@,我觉得这不太容易混淆。

SELECT resource->'subject' FROM resourcetable 
WHERE resource @> '{"resourceType": "MedicationRequest", "status":"active"}';

最后,您的两个查询实际上在某些条件下返回不同的结果,例如匹配 WHERE 的行没有键“主题”。


推荐阅读