如何在 Postgres 中为过去 90 天的记录创建索引使 now() 不可变

How to create index on records for last 90 days in Postgres Making now() immutable

我有一个案例,由于速度问题,我只想为过去 90 天的记录创建索引。

当我尝试创建这样的索引时:

create index if not exists idx_d1_section_learner_partial_date_modified
    on instruct.d1_section_learner (audit_modified_datetime)
    where (audit_modified_datetime >= '2019-07-01 00:00:00'::timestamp);

它有效,但我想保持这种动态,所以我尝试了这个:

create index if not exists idx_d1_section_learner_partial_date_modified
    on instruct.d1_section_learner (audit_modified_datetime)
    where (audit_modified_datetime >= now() - interval '90 days'::timestamp);

给出错误:

ERROR: functions in index predicate must be marked IMMUTABLE

我知道这是因为当前的时间戳。因为它在交易中不是恒定的。有什么办法可以避免这种情况吗?

或者我可以将 current_timestamp 标记为不可变的吗?

而不是不可变的 now() 函数(这是行不通的!)使用返回 timestamp 常量的伪不可变函数,并将您的部分索引基于它 - 以及您的应该使用它的查询。

此外,您不必必须每天更新索引。该索引可以包含几个过时的行,这几乎无关紧要。您只需向查询添加 exact 条件 additionally。随着添加更多行,性能会随着时间的推移 缓慢 下降。时不时重新创建函数和索引就足够了。可以是每周一次,有时数据库负载最低。

刚好我在6年前发了一个完整的解决方案:

  • Optimize performance for queries on recent rows of a large table

对其进行了一些更新以反映最近的发展。

旁白:now() returns timestamptz,而不是 timestampLOCALTIMESTAMP 会更合适。但是不要去那里。