Kat*_*amy 6 postgresql indexing where-clause
我想WHERE
在 Postgres 中添加一个带有子句的索引。我使用以下查询来执行此操作:
create index concurrently em_openorder_idx on line (m_product_id, org_id, date) where date >= now() - 90
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
functions in index predicate must be marked IMMUTABLE
Run Code Online (Sandbox Code Playgroud)
子句中的表达式WHERE
必须是不可变的,即对于给定的一组参数,每次调用它时都必须返回相同的值。now()
显然不符合条件。
您可以像这样索引过去 90 天的数据:
create index concurrently em_openorder_idx on line (m_product_id,org_id,date)
where date>='now'::date-90
Run Code Online (Sandbox Code Playgroud)
但是,如果您返回并查看索引定义,您会发现它已转换为常量表达式:
... WHERE date >= ('2016-03-02'::date - 90);
Run Code Online (Sandbox Code Playgroud)
换句话说,这个90天的窗口不会随着时间的推移而自动向前推进;您需要定期删除并重新创建该索引。
date
另一件需要注意的事情是,您的查询只有在与不可变表达式进行比较时才能使用此索引。例如,这里将使用索引:
SELECT * FROM line WHERE date = '2016-03-02';
Run Code Online (Sandbox Code Playgroud)
...但不能在这里使用:
SELECT * FROM line WHERE date = CURRENT_DATE;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您使用的是 Postgres 9.5,则该表可能是BRIN 索引的良好候选者。
只需创建索引
create index concurrently em_openorder_idx on line (m_product_id,org_id,date)
Run Code Online (Sandbox Code Playgroud)
我猜你想实现一个与此类似的查询
EXPLAIN ANALYZE
SELECT *
FROM line
WHERE m_product_id = @id
AND date>=now()-90
Run Code Online (Sandbox Code Playgroud)
这将使用索引并且应该非常快。