如何在Postgres中添加带WHERE子句的索引

时间:2016-03-01 13:14:56

标签: postgresql indexing where-clause

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

2 个答案:

答案 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

这将使用索引并且应该非常快。