Postgresql 对数据库视图进行筛选比直接查询慢得多

Postgresql 对数据库视图进行筛选比直接查询慢得多,postgresql,Postgresql,我注意到,在执行常规查询时,查询计划与创建数据库视图然后查询视图时有很大的不同 案例1基本查询: SELECT <somequery> WHERE <some-filter> <some-group-by> 选择位置 案例2数据库视图: CREATE VIEW myview AS SELECT <some-query> <some-group-by>; SELECT FROM myview WHERE <some-filter

我注意到,在执行常规查询时,查询计划与创建数据库视图然后查询视图时有很大的不同

案例1基本查询:

SELECT <somequery> WHERE <some-filter> <some-group-by>
选择位置
案例2数据库视图:

CREATE VIEW myview AS SELECT <some-query> <some-group-by>;
SELECT FROM myview WHERE <some-filter>;
CREATE VIEW myview AS SELECT;
从myview中选择WHERE;
我注意到,在这种情况下,2个postgres将加入/聚合所有可能的内容,只有这样它才会应用过滤器。在案例1中,它不涉及用where子句过滤掉的行。所以案例2要慢得多


在保留数据库视图的同时,是否有一些技巧可以解决此问题?

每次执行“选择自”时,视图都必须重新创建要筛选的数据集

最简单的方法是将视图更改为物化视图。如果您的数据不是每2分钟更改一次,则物化视图将保存要使用的选择,您的过滤器可以在其中处理“已保存”的数据集。您可以做的第二件事是在视图上添加索引

示例如下:

创建物化视图matview.account\u余额为
选择
名称
结合(

sum(amount)filter(其中post_time在一般情况下,我不相信这一点(在PG中,视图被视为宏,在选择计划之前与封闭查询混合在一起)。您是否绝对确定这些查询在逻辑上是相同的?您能否在问题中添加一个具体的示例来显示这种行为?例外情况可能是geqo(此查询的范围表有多大?)
create materialized view matview.account_balances as
select
  name,
  coalesce(
    sum(amount) filter (where post_time <= current_timestamp),
    0
  ) as balance
from accounts
  left join transactions using(name)
group by name;

create index on matview.account_balances (name);
create index on matview.account_balances (balance);