【问题标题】:Create timestamp index from JSON on PostgreSQL在 PostgreSQL 上从 JSON 创建时间戳索引
【发布时间】:2015-06-27 17:43:35
【问题描述】:

我在 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

我试图让它“不可变”,用

设置时区

date_trunc('seconds', CAST(data->>'created_at' AS timestamp) at time zone 'GMT')

但我仍然收到“不可变”错误。那么,如何从 JSON 中完成时间戳索引?我知道我可以用日期制作一个简单的列,因为它可能会在时间上保持不变,但我想学习如何做到这一点。

【问题讨论】:

  • 唯一的解决方法是创建自己的函数来进行转换(使用时区),将该函数声明为不可变,然后使用 that 函数作为索引。

标签: postgresql jsonb


【解决方案1】:

索引中也不允许此表达式:

(CAST(data->>'created_at' AS timestamp) at time zone 'UTC')

它不是一成不变的,因为第一次转换取决于您的 DateStyle 设置(除其他外)。 在函数调用之后将结果转换为 UTC 无济于事,不确定性已经潜入...

解决方案是一个通过固定时区使演员不可变的函数(如@a_horse already hinted)。

我建议使用to_timestamp()(也只是STABLE,而不是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'));

此相关答案中对此技术的详细说明:

相关:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多