MATERIALIZED VIEW — PostgreSQL
GÖRSELDEKI QR KODU KULLANARAK ILETISIM KANALLARIMDAN BANA ULASABILIRSINZ
Şu an çalıştığım firmada şirketteki ilk taskım Materialized View’ların refresh edilmesiydi. (:
Bu konuyu okumadan önce, buradan PostgreSQL’deki View yazımı okumanızı tavsiye ederim.
Çok temel ifadeyle materialized view’lar aslında “veriyi fiziksel olarak depolayan” view türüdür. Bu yüzden veri her sorgulandığında kaynağa gidip veriyi yeniden çekmek yerine depolanmış halini kullanır. Normal bir view’da ise olay aslında şudur. Veri her sorgulandığında yeniden çekilir. Bu nedenle daha büyük verilerde ya da karmaşık sorgularda veri güncellenmediği sürece sorgular daha hızlı sonuçlanır.
Materialized View vs View
- View: Veri Depolanmaz, her sorguda yeniden çekilir.
Materialized View: Veri fiziksel olarak depolanır. - View: Veritabanında veri her seferinde yeniden çekildiği için performans kaybı yaşanabilir.
Materialized View: Veriyi fiziksel olarak sakladığı için aynı sorgu tekrarlandığında daha hızlı çalışır. - View: Her sorguda güncel veriyi çeker.
Materialized View: Güncel veriyi çekebilmesi için manuel bir işlem gerektirir.
Materialized View Oluşturma
1.Adım
Öncelikle bir tablo oluşturarak işe başlayalım.
create table user_roles(
id SERIAL PRIMARY KEY,
role_name varchar(50) not null unique,
access_level INTEGER not null,
authority varchar not null
);
2.Adım
Bu oluşturduğumuz tabloya kayıt insert edelim.
INSERT INTO user_roles (role_name, access_level, authority) VALUES
('Super Admin', 1, 'add user, add admin, delete user, delete admin,
read, write, delete, update'),
('Admin', 2, 'add user, read, write, delete, update'),
('Editor', 3, 'read, update');
3.Adım
Şimdi Materialized View oluşturarak devam edelim.
--Formülü
--CREATE MATERIALIZED VIEW materialized_view_name AS (Select Statement)
CREATE MATERIALIZED VIEW authority_read AS
SELECT role_name, access_level FROM user_roles
WHERE authority like '%read%'
Burada yapılan işlem aslında şu. authority’si içerisinde read yetkisi olanları bir materialized view içerisine alıyoruz. Bu kodu çalıştırdığımda (Ben client olarak DataGrip kullanıyorum) hemen sol tarafta materialized view alanının oluştuğunu ve içerisine bizim oluşturduğumuz materialized view’ın geldiğini görebiliriz.
4.ADIM
Bu oluşturduğumuz materialized view’ı ise aşağıdaki şekilde kullanabiliriz.
select * from authority_read
Ve dahası normal bir tabloya ne yapıyorsak bu oluşturduğumuz özel view’a da aynılarını yapabiliriz.
SORU
Asıl tabloya veri eklersem ne olur.? Materialized View nasıl davranır.?
El-cevap:
Asıl tabloya veri eklendiğinde, materialized view’da hiç bir şey olmaz. Çünkü en başta da bahsettiğim gibi güncel verinin çekilebilmesi için bir refresh işlemine tabi tutulması lazım. Bunun için ise aşağıdaki kodu kullanabiliriz.
--Formül
--REFRESH MATERIALIZED VIEW materialized_view_name
REFRESH MATERIALIZED VIEW authority_read
SORU
Normal view ile materialized view’ların performans farklarını nasıl karşılaştırabilirim.?
El-cevap
Bunun için Explain Analyze kullanılabilir. Az sayıda veri içeren tablolarda bu anlaşılmaz ama 100K tane veri içeren tablolar üzerinde hem materialized view’a hem de normal view’a explain analyze işlemi uygulanarak performans farkları karşılaştırılabilir. bunun için yapılması gereken ise aşağıdaki gibidir.
EXPLAIN ANALYZE SELECT * FROM view_name
EXPLAIN ANALYZE SELECT * FROM matherialized_view_name
SORU 4
Şirketimdeki problem neydi ve ben bunu nasıl çözdüm.?
El-cevap
Aslında konu basitti. Bir materialized view vardı ve bu materialized view’a çok sık olmasa da veri güncellenmesi yapılıyordu ve veri ekleniyordu. Belli başlı grafiklerde bu materialized view’a göre şekilleniyordu. Veri eklendikçe manuel olarak bu materialized view’ın güncellenmesi gerekiyordu. Bunu endpoint seviyesine taşıdım. Python ile bir endpoint yazdım ve native sql kodu ile bunun güncellenmesini sağladım. Native SQL yazdım çünkü bu durum aslında PostgreSQL’e bağlı bir durumdu. Ama bu konu PG_CRON ile de çözülebilirdi.