Widoki zmaterializowane

Widoki zmaterializowane to taki rodzaj widoku, który przechowuje wynik zapytania. Bliżej im w zasadzie do tabel budowanych na zasadzie CREATE TABLE XYZ AS SELECT … niż do zwykłych widoków. Różnice jednak są takie, że na widokach zmaterializowanych nie można wykonywać operacji UPDATE, INSERT ani DELETE, ale za to mogą być odświeżane. Widoki zmaterializowane zostały wprowadzone w wersji 9.3 PostgreSQL.

Stosuje się je najczęściej przy wyliczaniu agregatów tam gdzie wyliczenie wyniku zajmuje dużo czasu a dane źródłowe nie zmieniają się zbyt często. Taki przykład z życia wzięty. Pracujemy ostatnio nad portalem ze zleceniami online. Zlecenia są przypisane do kategorii i podkategorii. Teraz mamy zapytanie tego typu:


select nazwa_kategorii,count(*) liczba_zlecen

from kategorie k join zlecenia z on (k.id_kategorii=z.id_kategorii)

group by nazwa_kategorii;


Czyli po prostu lista kategorii zleceń i liczba zleceń przypisana do owych kategorii. Przy dużej liczbie zleceń takie zapytanie będzie mieliło dosyć długo, a tymczasem wynik tego zapytania musi być szybko wyświetlony na stronie. Ilość zleceń w poszczególnych kategoriach się zbyt często nie zmienia. W zasadzie tylko w przypadku dodania nowego zlecenia. Możemy więc stworzyć widok zmaterializowany oparty o takie zapytanie, a następnie odwoływać się do niego. Odczyt będzie znacznie szybszy, ponieważ nie będą mielone dane źródłowe a zostanie po prostu odczytany gotowy wynik:


create materialized view liczba_zlecen_kategorie as

select nazwa_kategorii,count(*) liczba_zlecen from kategorie k join zlecenia z on (k.id_kategorii=z.id_kategorii)

group by nazwa_kategorii;


Odwołanie się do takiego widoku odbywa się identycznie jak do tabeli:


select * from liczba_zlecen_kategorie;


Ponowne przeładowanie zawartości widoku zmaterializowanego odbywa się za pomocą wywołania klauzuli REFRESH:


refresh materialized view liczba_zlecen_kategorie ;


Musisz wiedzieć że refresh powoduje exclusive lock na obiektach źródłowych na czas odświeżania. W tym przypadku będzie to dotyczyło tabel kategorie i zlecenia. Istnieje też możliwość dosyć nietypowego odświeżenia – bo z wyczyszczeniem zawartości – zachowana zostanie jedynie struktura:


refresh materialized view liczba_zlecen_kategorie with no data;


Możesz też od razu stworzyć widok zmaterializowany bez danych:


create materialized view lzk as select * from liczba_zlecen_kategorie with no data;


Informacje o istniejących widokach zmaterializowanych i zapytaniach na bazie których powstały znajdziesz w słowniku pg_matviews:


select * from pg_matviews;





Ten artykuł jest elementem poniższych kursów: