3

我在 Postgresql 9.1 中有几百万行的大表。其中一列是带有时区的时间戳。

常用查询是使用 where 子句'column > (now()::date - 11)'查找最近十天的数据。

我想建立一个仅适用于上个月数据的索引,以限制扫描。部分索引。

到目前为止,我还没有弄清楚如何使用上个月的实际,所以我开始硬编码“2015-12-01”作为索引的开始日期。

create index q on test (i) where i > '2015-01-01';

这工作正常,索引已创建。但不幸的是,它没有被使用,因为它把 '2015-01-01' 当作一个::timestamp,而查询是一个::date. 所以没有使用索引,我回到了第一方。

接下来,我尝试修改索引以将列与日期进行比较,以便匹配。但在这里,我碰到了不可变的墙。

作为可变函数to_datecast as date它们依赖于本地时区,索引创建失败。

如果我有这样的测试表:

create table test (i timestamptz);

然后尝试创建索引

create index q on test (i) where i > to_date('2015-01-01','YYYY-DD-MM');

然后它失败了

ERROR:  functions in index predicate must be marked IMMUTABLE

这是可以理解的。但是现在,当我尝试使用特定时区时

create index q on test (i) where i > to_date('2015-01-01','YYYY-DD-MM') 
at time zone 'UTC';

它仍然失败

ERROR:  functions in index predicate must be marked IMMUTABLE

这我不明白了。它定义了时区。还有什么是不可变的?

我也尝试自己创建不可变函数:

CREATE FUNCTION
datacube=# create or replace function immutable_date(timestamptz) returns date as $$
select ($1::date at time zone 'UTC')::date;
$$ language sql immutable;

但是在索引中使用这个函数:

create index q on test (i) where i > immutable_date('2015-01-01');

失败并出现相同的错误:

ERROR:  functions in index predicate must be marked IMMUTABLE

我在这里不知所措。也许它与语言环境有关,而不仅仅是时区?或者其他什么使它可变?

而且 - 也许还有另一种更简单的方法,将索引限制为上一两个月的数据?Postgres 中的表分区需要重建整个数据库,到目前为止我还没有找到其他任何东西。

4

0 回答 0