Sie sollten die Ansicht in Triggern nach dem Einfügen/Aktualisieren/Löschen/Truncate für jede Anweisung in table1
aktualisieren und table2
.
create or replace function refresh_mat_view()
returns trigger language plpgsql
as $$
begin
refresh materialized view mat_view;
return null;
end $$;
create trigger refresh_mat_view
after insert or update or delete or truncate
on table1 for each statement
execute procedure refresh_mat_view();
create trigger refresh_mat_view
after insert or update or delete or truncate
on table2 for each statement
execute procedure refresh_mat_view();
Auf diese Weise ist Ihre materialisierte Ansicht immer aktuell. Diese einfache Lösung könnte bei häufigen Einfügungen/Aktualisierungen und sporadischen Auswahlen schwer zu akzeptieren sein. In Ihrem Fall (seltene Änderungen etwa zweimal am Tag) entspricht sie ideal Ihren Anforderungen.
Um eine verzögerte Aktualisierung zu realisieren einer materialisierten Ansicht benötigen Sie eine der folgenden Funktionen:
- asynchroner Trigger
- Trigger vor Auswahl
- Vorher auswählen
Postgres hat keine davon, also scheint es keine klare zu geben Postgres-Lösung.
In Anbetracht dessen würde ich eine Wrapper-Funktion für Auswahlen auf mat_view in Betracht ziehen, z. B.
CREATE OR REPLACE FUNCTION select_from_mat_view(where_clause text)
RETURNS SETOF mat_view AS $body$
BEGIN
-- here is checking whether to refresh the mat_view
-- then return the select:
RETURN QUERY EXECUTE FORMAT ('SELECT * FROM mat_view %s', where_clause);
END;
$body$ LANGUAGE plpgsql;
Ob es in der Praxis akzeptabel ist, hängt von Einzelheiten ab, die mir nicht bekannt sind.