在相关事务后触发一次更新物化视图?

Nat*_*ong 4 postgresql materialized-view fast-refresh postgresql-9.6

我正在使用 PostgreSQL 9.6。

我有一个物化视图来支持跨两个表的全文搜索,我将其称为poststags。这些表格很少更新和频繁搜索。

我试图找到一个好的策略来运行REFRESH MATERIALIZED VIEW post_search.

理想的解决方案会是这样的触发器:在任何交易修饰的(或之后)的端部poststags和/或posts_tags(连接表),刷新物化视图正好一次

我怎么能做到这一点?

Nat*_*ong 6

使用触发器的 OK 解决方案

这就是我现在正在做的。这不正是我想要的东西,因为触发器触发每一次发言,而不是每一次交易。但它现在有效。

(将来,我们正在考虑使用实际表而不是物化视图进行搜索,并通过触发器更新各个相关行而不是刷新整个 matview。)

创建一个函数来同时刷新物化视图:

  CREATE OR REPLACE FUNCTION refresh_post_search()
  RETURNS TRIGGER LANGUAGE plpgsql
  AS $$
  BEGIN
  REFRESH MATERIALIZED VIEW CONCURRENTLY post_search;
  RETURN NULL;
  END $$;
Run Code Online (Sandbox Code Playgroud)

并为每个基础表创建一个触发器:

  CREATE TRIGGER refresh_post_search
  AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE
  ON posts
  FOR EACH STATEMENT
  EXECUTE PROCEDURE refresh_post_search();

  CREATE TRIGGER refresh_post_search
  AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE
  ON posts_tags
  FOR EACH STATEMENT
  EXECUTE PROCEDURE refresh_post_search();

  CREATE TRIGGER refresh_post_search
  AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE
  ON tags
  FOR EACH STATEMENT
  EXECUTE PROCEDURE refresh_post_search();
Run Code Online (Sandbox Code Playgroud)

  • @CodingGorilla 我在 http://nathanmlong.com/2018/01/fast-fulltext-search-with-ecto-and-postgresql/ 写了详细信息 (2认同)

Eva*_*oll 5

嗯,很可能你做错了。虽然动词REFRESH可能有其他含义,但在运行该表时实际上是在重写该表。这种工作负载在触发器中运行是很重的(尽管你可以)。

这没有多大意义。你要么

  1. 不想要一个MATERIALIZED VIEW;
  2. REFRESH希望在停机时间、休息时间或定期期间制定策略。

第二个通常是用

  1. 一个简单的 cron、pg_cron
  2. 导入结束时

通常,您需要

  • 永远正确:使用简单的视图。
  • 定期正确:使用物化视图。
  • 流畅且正确:您可以检查NOTIFY/EVENT时间序列数据库

a 很可能MATERIALIZED VIEW根本不是您想要的。