Du bør opdatere visningen i triggere efter indsæt/opdater/slet/truncate for hver sætning på table1
og 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();
På denne måde er din materialiserede visning altid opdateret. Denne enkle løsning kan være svær at acceptere med hyppige indsættelser/opdateringer og sporadiske valg. I dit tilfælde (ændres sjældent omkring to gange om dagen) passer den ideelt til dine behov.
At realisere udskudt opdatering af en materialiseret visning har du brug for en af følgende funktioner:
- asynkron trigger
- udløs før valg
- reglen om vælg før
Postgres har ingen af dem, så det ser ud til, at der ikke er nogen klar postgres løsning.
Med dette i betragtning vil jeg overveje en indpakningsfunktion til udvalgte på mat_view, f.eks.
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;
Om det er acceptabelt i praksis afhænger af detaljer, jeg ikke kender til.