我有一个关于PostgreSQL的表,其中一个名为data
的字段是jsonb
,包含很多对象,我想制作一个索引来加速查询。我使用少量行来测试数据(只有15行),但我不希望将来遇到查询问题。我从Twitter API获取数据,因此在一周内我获得了大约10GB的数据。
如果我做正常指数
CREATE INDEX ON tweet((data->>'created_at'));
如果我做的话,我会得到一个文本索引:
Create index on tweet((CAST(data->>'created_at' AS timestamp)));
我得到了
ERROR: functions in index expression must be marked IMMUTABLE
我已经尝试过这样做了#34; inmutable"使用
设置时区 date_trunc('seconds', CAST(data->>'created_at' AS timestamp) at time zone 'GMT')
但我仍然得到了"不可变的"错误。那么,我如何从JSON中完成时间戳索引?我知道我可以用日期制作一个简单的专栏,因为它可能会在当时保持不变,但我想学习如何做到这一点。
答案 0 :(得分:6)
这个表达式不允许在索引中使用:
(CAST(data->>'created_at' AS timestamp) at time zone 'UTC')
它不是一成不变的,因为第一次演员取决于你的DateStyle
设置(以及其他内容)。在函数调用之后将结果转换为UTC 没有帮助,不确定性已经悄悄进入......
解决方案是通过修复时区(例如@a_horse already hinted)使使转换为不可变的函数。
我建议使用to_timestamp()
代替演员(也不是IMMUTABLE
)来排除一些麻烦来源 - DateStyle
是一个。
CREATE OR REPLACE FUNCTION f_cast_isots(text)
RETURNS timestamptz AS
$$SELECT to_timestamp($1, 'YYYY-MM-DD HH24:MI')$$ -- adapt to your needs
LANGUAGE sql IMMUTABLE;
请注意,这会返回timestamptz
。然后:
CREATE INDEX foo ON t (f_cast_isots(data->>'created_at'));
此相关答案中此技术的详细说明:
相关: