postgresql - Postgresql - jsonb 列中日期字段的索引策略
问题描述
处理 jsonb 列中的日期字段是否有任何最佳实践?在以下场景中,我试图根据出生日期查找“患者”。
SELECT P.resource ->> 'id' ID, P.resource -> 'birthDate' DoB, CONCAT(P.resource -> 'name' -> 0 -> 'given', ' ', P.resource -> 'name' -> 0 -> 'family') "name"
FROM recorditems P
WHERE P.resource ->> 'resourceType' = 'Patient'
AND (P.resource ->> 'birthDate')::date BETWEEN '1975-01-01'::date AND '1995-01-01'::date;
如果我使用@>
运算符重写第一个谓词,则 gin 索引可能会派上用场。对第二个谓词有任何索引建议吗?字符串到日期的转换不会是性能开销吗?
explain analyze
说:
Gather (cost=1000.00..229569.96 rows=39 width=96) (actual time=6.178..1205.812 rows=699 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on recorditems p (cost=0.00..228566.06 rows=16 width=96) (actual time=13.747..1172.495 rows=233 loops=3)
Filter: (((resource ->> 'resourceType'::text) = 'Patient'::text) AND (((resource ->> 'birthDate'::text))::date >= '1975-01-01'::date)
AND (((resource ->> 'birthDate'::text))::date <= '1995-01-01'::date))
Rows Removed by Filter: 524492
Planning Time: 0.068 ms
JIT:
Functions: 12
Options: Inlining false, Optimization false, Expressions true, Deforming true
Timing: Generation 2.296 ms, Inlining 0.000 ms, Optimization 0.891 ms, Emission 16.132 ms, Total 19.320 ms
Execution Time: 1206.889 ms
(12 rows)
Time: 1207.337 ms (00:01.207)
解决方案
该查询的完美索引是:
CREATE INDEX ON recorditems (
(resource ->> 'resourceType'),
((resource ->> 'birthDate')::date)
);
那是行不通的,因为从text
todate
的转换不是IMMUTABLE
(尝试SELECT 'today'::date;
)。
如果您知道只存储了 ISO 日期,则可以使用自定义函数解决此问题:
CREATE FUNCTION text_to_date(text) RETURNS date
IMMUTABLE LANGUAGE sql AS
'SELECT CAST($1 AS date)';
然后您必须在查询和索引中使用该功能:
CREATE INDEX ON recorditems (
(resource ->> 'resourceType'),
(text_to_date(resource ->> 'birthDate'))
);
推荐阅读
- swift - Firebase iOS annotateImage 函数返回“位置 1 的 JSON 中的意外令牌 o”
- c#-3.0 - 如何配置这个冒泡排序?它给了我一个属性错误或索引器可能无法通过?
- javascript - javascript 在 script.onerror 发生时分配变量值
- r - 如何逐个单元格地将字符串附加到两个不同的数据表中?
- scala - 如何加载 Scala 依赖项?
- excel - 蒙特卡罗与PERT分布EXCEL
- javascript - 返回数组中的最大数,我做错了什么?
- odoo - 如何从odoo12迁移到version14
- angular - 在 Angular 9 中实施 Rendertron 并部署到 AWS S3
- terraform - 在 terraform 变量中设置多行值