Postgresql

相關事務後觸發一次更新物化視圖?

  • December 27, 2018

我正在使用 PostgreSQL 9.6。

我有一個物化視圖來支持跨兩個表的全文搜尋,我將其稱為poststags。這些表不經常更新和經常搜尋。

我試圖找到一個好的策略來執行REFRESH MATERIALIZED VIEW post_search

理想的解決方案是這樣的觸發器:在任何修改和****/或(連接表)的****事務結束時(或之後),只刷新一次實體化視圖posts``tags``posts_tags

我怎麼能做到這一點?

使用觸發器的 OK 解決方案

這就是我現在正在做的事情。這不是想要的,因為觸發器在每個語句中觸發一次,而不是在每個事務中觸發一次。但它現在有效。

(在未來,我們正在考慮使用實際表進行搜尋而不是物化視圖,並通過觸發器更新各個相關行而不是刷新整個 matview。)

創建一個函式來同時刷新物化視圖:

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

並為每個基礎表創建一個觸發器:

 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();

好吧,很可能你做錯了。雖然動詞REFRESH可能有其他含義,但您實際上是在執行表時重寫了它。在觸發器中執行這種工作負載很重(儘管您可以)。

這沒有多大意義。你要麼

  1. 不想一個MATERIALIZED VIEW;
  2. 想要REFRESH在停機時間、休息時間或定期進行策略。

第二個通常是用

  1. 一個簡單的 cron、pg_cron或類似的
  2. 在導入結束時

通常,您要麼需要

  • 永遠正確:使用普通視圖。
  • 週期性正確:使用物化視圖。
  • 流動性和正確性:您可以檢查NOTIFY/EVENT或時間序列數據庫

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

引用自:https://dba.stackexchange.com/questions/190552