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

问题描述 投票:1回答:2

我想在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
postgresql indexing where-clause
2个回答
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的一个很好的候选者。


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

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

© www.soinside.com 2019 - 2024. All rights reserved.