内部函数查询不使用索引

时间:2016-10-11 10:10:53

标签: sql postgresql

我有这样的查询:

SELECT f.id_foo
FROM foo f
WHERE date_trunc('day'::text, current_date - '597 days'::interval) > date_trunc('day'::text, f.my_date);

它正如我想的那样工作。它使用date_trunc_index

CREATE INDEX date_trunc_index
ON foo
USING btree
(date_trunc('day'::text, my_date));

我们假设这个查询在其他函数/查询/视图中,我希望通过返回get_days()的函数interval来控制天数

我的查询如下:

SELECT f.id_foo
FROM foo f
WHERE date_trunc('day'::text, current_date - get_days()) > date_trunc('day'::text, f.my_date);

我的问题是:为什么第二个查询不再使用date_trunc_index了?以及如何解决这个问题?

修改

EXPLAIN ANALYZE

第一次查询:

"Index Scan using date_trunc_index on foo f  (cost=0.01..8.10 rows=1 width=8) (actual time=0.012..0.012 rows=0 loops=1)"
"  Index Cond: (date_trunc('day'::text, (('now'::cstring)::date - '597 days'::interval)) > date_trunc('day'::text, my_date))"
"Total runtime: 0.049 ms"

第二次查询:

"Seq Scan on foo f  (cost=0.00..4228786.45 rows=2993719 width=8) (actual time=56384.159..56384.159 rows=0 loops=1)"
"  Filter: (date_trunc('day'::text, (('now'::cstring)::date - get_days())) > date_trunc('day'::text, my_date))"
"  Rows Removed by Filter: 8980835"
"Total runtime: 56384.181 ms"

1 个答案:

答案 0 :(得分:1)

Postgres具有三个用于优化查询的函数的重要特征:不可变,稳定和易失性函数。

在单次运行查询期间,前两个是“常量”。这意味着优化器可以将它们视为常量。易失性函数 - 例如random() - 每次调用时都会返回不同的值。

create function documentation中解释了这些内容。