我在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_date
或cast 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
这是understandable。但现在,当我尝试使用特定的时区时
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
我在这里不知所措。也许它与Locales有关,而不仅仅是时区?或者其他什么使它变得可变?
而且 - 也许还有另一种更简单的方法来将索引限制为上个月或两个数据? Postgres中的表分区需要重建整个数据库,到目前为止我还没有找到任何其他内容。