如何解决Postgres 触发刷新物化视图一段时间后不起作用
我创建了一个物化视图和一个触发器,用于在对源表进行任何更新后刷新它。
似乎一切正常,但一段时间后似乎触发器停止工作,因为物化视图仍然保留陈旧数据。
在我重新创建触发器后的某个时刻,该功能再次开始工作。
11 中使用的 postgres 版本。
CREATE OR REPLACE FUNCTION refresh_some_view()
RETURNS TRIGGER
LANGUAGE PLPGsql
AS
$$
BEGIN
REFRESH MATERIALIZED VIEW some_view;
RETURN NEW;
END;
$$;
CREATE TRIGGER on_source_table_update
AFTER UPDATE OR INSERT OR DELETE
ON source_table
FOR EACH ROW
EXECUTE PROCEDURE refresh_some_view();
解决方法
使用 FOR EACH STATEMENT
而不是 FOR EACH ROW
。这将阻止在插入语句的每一行之后刷新视图,这很可能不是您想要的。
CREATE TRIGGER on_source_table_update
AFTER UPDATE OR INSERT OR DELETE ON source_table
FOR EACH STATEMENT EXECUTE PROCEDURE refresh_some_view();
您可以在查询规划器中查看。如果您使用 FOR EACH STATEMENT
,则函数中的刷新将仅被调用一次 - 请参阅 Trigger on_source_table_update
处的调用次数。此查询计划显示了包含 1000 行的插入会发生什么 - 请参阅 rows
处的数字 ProjectSet
:
QUERY PLAN
------------------------------------------------------------------------------
Insert on source_table (actual time=7.097..7.140 rows=0 loops=1)
-> ProjectSet (actual time=0.005..0.398 rows=1000 loops=1)
-> Result (actual time=0.002..0.044 rows=1 loops=1)
Planning Time: 0.264 ms
Trigger on_source_table_update: time=11.628 calls=1
Execution Time: 19.011 ms
...但是如果你坚持 FOR EACH ROW
事情会变得更慢,因为触发器每行调用一次函数(1000 次!):
QUERY PLAN
------------------------------------------------------------------------------
Insert on source_table (actual time=4.187..4.188 rows=0 loops=1)
-> ProjectSet (actual time=0.004..0.204 rows=1000 loops=1)
-> Result (actual time=0.002..0.002 rows=1 loops=1)
Planning Time: 0.122 ms
Trigger on_source_table_update: time=13815.499 calls=1000
Execution Time: 13820.529 ms
演示:PIL
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。