我想在Postgres中添加一个带有WHERE
子句的索引。我使用以下查询来做到这一点:
create index concurrently em_openorder_idx on line (m_product_id, org_id, date) where date >= now() - 90
但是我收到以下错误:
functions in index predicate must be marked IMMUTABLE
答案 0 :(得分:2)
WHERE
子句中的表达式必须是immutable,即对于给定的参数集,每次调用它时都必须返回相同的值。 now()
显然没有资格。
您可以将最近90天的数据编入索引,如下所示:
create index concurrently em_openorder_idx on line (m_product_id,org_id,date)
where date>='now'::date-90
但是,如果您回过头来查看索引定义,您会看到它已被转换为常量表达式:
... WHERE date >= ('2016-03-02'::date - 90);
换句话说,这个90天的窗口不会随着时间的推移自动向前移动;您需要自己定期删除并重新创建此索引。
另一点需要注意的是,如果您的查询将date
与不可变表达式进行比较,那么您的查询只能使用此索引。例如,索引将在这里使用:
SELECT * FROM line WHERE date = '2016-03-02';
...但不能在这里使用:
SELECT * FROM line WHERE date = CURRENT_DATE;
顺便说一句,如果您使用Postgres 9.5,此表可能是BRIN index的合适人选。
答案 1 :(得分:0)
只需创建索引
create index concurrently em_openorder_idx on line (m_product_id,org_id,date)
我猜你想要实现类似于这个的查询
EXPLAIN ANALYZE
SELECT *
FROM line
WHERE m_product_id = @id
AND date>=now()-90
这将使用索引并且应该非常快。