Materialized View: Kapan Perlu Cache Hasil Query
TL;DR
Materialized view adalah objek database yang menyimpan hasil sebuah query secara fisik ke disk, beda dengan view biasa yang menghitung ulang tiap kali dipanggil. Karena hasilnya udah jadi, query yang berat bisa dibaca dalam milidetik. Konsekuensinya: datanya bisa basi sampai kamu jalanin REFRESH, dan dia makan storage.
Materialized view adalah objek database yang menyimpan hasil sebuah query secara fisik ke disk, jadi waktu dibaca dia gak perlu menghitung ulang apa pun.
View biasa itu kayak resep. Tiap kali dibuka, dimasak lagi dari awal. Materialized view itu masakannya yang udah jadi dan disimpan di kulkas.
Di sini kamu bakal tau bedanya secara teknis, angka nyata dari dataset toko_berkah, cara REFRESH tanpa bikin dashboard nge-freeze, dan kapan materialized view justru bikin masalah baru.
Apa itu materialized view?
Materialized view adalah tabel hasil query yang disimpan permanen di disk dan bisa dibaca kayak tabel biasa. Isinya gak otomatis ikut berubah waktu tabel sumbernya diupdate. Kamu harus jalanin perintah REFRESH buat menyegarkannya.
Bandingin sama view biasa yang cuma nyimpen teks querynya. View gak makan storage, tapi tiap dibaca dia jalanin ulang semua JOIN dan GROUP BY dari nol.
| Aspek | View | Materialized view |
|---|---|---|
| Yang disimpan | Teks query | Hasil query |
| Storage | Nyaris nol | Sebesar hasilnya |
| Kecepatan baca | Selambat query aslinya | Secepat baca tabel |
| Kesegaran data | Selalu terkini | Sesuai REFRESH terakhir |
| Bisa di-index | Gak | Bisa |
Baris terakhir itu yang sering dilupain. Materialized view bisa dikasih index, dan itu yang bikin dia bisa secepat tabel biasa.
Kapan materialized view beneran ngebantu?
Tiga kondisi yang bikin dia masuk akal.
Querynya berat dan dibaca berkali-kali. Dashboard yang dibuka 200 orang tiap pagi, isinya query dengan 4 JOIN dan agregasi jutaan baris. Hitung sekali, baca 200 kali.
Data sumbernya jarang berubah. Ringkasan penjualan kemarin gak bakal berubah lagi hari ini. Buat apa dihitung ulang tiap ada yang buka dashboard.
Data basi beberapa jam masih bisa diterima. Laporan omzet bulanan gak butuh presisi detik. Kalau angkanya telat 1 jam, gak ada yang rugi.
Kalau ketiganya kena, materialized view biasanya keputusan yang bener.
Contoh kasus: dashboard toko_berkah yang loading 8 detik
Dataset toko_berkah di Ngulik Data punya 1,4 juta baris transaksi dari 6 cabang UMKM. Dashboard omzet hariannya narik data lewat query ini.
SELECT
t.tanggal,
c.nama_cabang,
COUNT(*) AS jumlah_transaksi,
SUM(t.qty * t.harga_jual) AS omzet,
SUM(t.qty * (t.harga_jual - p.hpp)) AS margin
FROM transaksi t
JOIN produk p ON p.kode = t.kode_produk
JOIN cabang c ON c.id = t.cabang_id
WHERE t.status = 'selesai'
GROUP BY t.tanggal, c.nama_cabang;
Waktu eksekusinya 8,4 detik. Dashboard dibuka rata-rata 40 kali per hari. Total 5,6 menit CPU kebuang tiap hari cuma buat menghitung ulang angka yang sama.
Bikin materialized view-nya.
CREATE MATERIALIZED VIEW mv_penjualan_harian AS
SELECT
t.tanggal,
c.nama_cabang,
COUNT(*) AS jumlah_transaksi,
SUM(t.qty * t.harga_jual) AS omzet,
SUM(t.qty * (t.harga_jual - p.hpp)) AS margin
FROM transaksi t
JOIN produk p ON p.kode = t.kode_produk
JOIN cabang c ON c.id = t.cabang_id
WHERE t.status = 'selesai'
GROUP BY t.tanggal, c.nama_cabang;
Hasilnya cuma 2.190 baris. Tiga tahun data harian dikali 6 cabang.
Kasih index biar filter tanggalnya makin ngebut.
CREATE UNIQUE INDEX idx_mv_penjualan
ON mv_penjualan_harian (tanggal, nama_cabang);
Sekarang dashboardnya baca dari sini.
SELECT nama_cabang, SUM(omzet) AS omzet_bulan
FROM mv_penjualan_harian
WHERE tanggal >= DATE '2026-03-01'
GROUP BY nama_cabang
ORDER BY omzet_bulan DESC;
Waktu eksekusi: 0,2 detik. Dari 8,4 detik jadi 0,2 detik, sekitar 42 kali lebih cepat.
Yang berubah bukan kecerdasan querynya. Kerjaan beratnya cuma dipindah dari jam sibuk ke jam 2 pagi.
Gimana cara REFRESH tanpa bikin dashboard nge-freeze?
REFRESH biasa mengunci materialized view selama proses berjalan. Kalau ada orang yang lagi buka dashboard, dia bakal nunggu.
REFRESH MATERIALIZED VIEW mv_penjualan_harian;
-- Pembaca lain kena lock sampai selesai
PostgreSQL punya opsi yang lebih sopan.
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_penjualan_harian;
-- Pembaca tetap bisa akses data lama selama refresh jalan
Syaratnya: materialized view-nya harus punya UNIQUE INDEX. Itu alasan kenapa index tadi bukan opsional.
Buat penjadwalan, cara paling umum di PostgreSQL pakai ekstensi pg_cron.
SELECT cron.schedule(
'refresh-penjualan',
'0 2 * * *',
$$REFRESH MATERIALIZED VIEW CONCURRENTLY mv_penjualan_harian$$
);
Jam 2 pagi, tiap hari. Penjelasan sintaks lengkapnya ada di dokumentasi resmi PostgreSQL untuk CREATE MATERIALIZED VIEW.
Kesalahan umum yang bikin materialized view jadi beban
Refresh kelewat sering
Aku pernah lihat tim nge-set refresh tiap 5 menit buat dashboard yang dibuka 3 kali sehari. Query refresh-nya 8 detik, jadi database menghabiskan 38 menit CPU per hari buat melayani 3 pageview.
Lupa bikin unique index
Tanpa itu, kamu gak bisa pakai CONCURRENTLY, dan tiap refresh bakal ngunci dashboard buat semua orang.
Dipakai buat data yang harus real-time
Stok gudang, saldo rekening, kursi bioskop. Data basi 5 menit di kasus kayak gini bisa bikin barang kejual dua kali. Pakai index di tabel aslinya, bukan materialized view.
Numpuk materialized view yang gak dipakai
Tiap materialized view yang idle tetap makan storage dan tetap ikut antre refresh. Setiap kuartal, cek mana yang beneran dibaca dan hapus sisanya.
Semua refresh dijadwalkan di jam yang sama
Dua puluh materialized view yang refresh bareng jam 2 pagi bikin database kamu megap-megap. Kasih jarak 5-10 menit antar job.
FAQ
Apa bedanya view sama materialized view?
View cuma nyimpen teks querynya dan dijalanin ulang tiap dibaca. Materialized view nyimpen hasilnya ke disk. View selalu fresh tapi lambat kalau querynya berat. Materialized view cepat tapi datanya sesuai REFRESH terakhir.
Database apa aja yang dukung materialized view?
PostgreSQL, Oracle, dan SQL Server (namanya indexed view). BigQuery dan Snowflake juga punya dengan refresh otomatis. MySQL gak punya bawaan, jadi orang bikin tabel ringkasan manual plus scheduled job.
Seberapa sering materialized view harus di-refresh?
Tergantung seberapa basi data yang masih bisa diterima. Dashboard harian cukup tiap jam. Laporan bulanan cukup sekali sehari. Jangan refresh tiap menit kalau yang buka cuma 5 orang per hari.
Apakah materialized view bikin database jadi berat?
Dia makan storage, dan proses REFRESH-nya berat karena menjalankan query aslinya dari awal. Jadwalkan refresh bergiliran dan hapus yang udah gak dipakai.
Kapan sebaiknya gak pakai materialized view?
Kalau datanya harus real-time kayak stok gudang. Juga kalau querynya udah di bawah 300 milidetik, nambah materialized view cuma nambah maintenance.
Penutup
Tiga hal yang perlu kamu ingat. Materialized view memindahkan kerjaan berat dari jam sibuk ke jam sepi, bukan menghilangkannya. Unique index itu wajib kalau kamu mau refresh tanpa ngunci pembaca. Dan data basi itu harga yang harus kamu bayar, jadi pastiin bisnisnya sanggup nerima.
Cek query paling lambat di dashboard kamu sekarang. Kalau dia dibaca puluhan kali sehari dan datanya jarang berubah, itu kandidat pertama.
Kalau kamu masih ngerasa query-nya lambat bahkan setelah pakai materialized view, biasanya masalahnya di index. Latihan bikin dan baca materialized view dari data asli bisa kamu coba langsung di NgulikSQL tanpa install database.
Lanjut baca stored procedure SQL kalau kamu mau otomatisin proses refresh-nya sekalian.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel Terkait
Churn Rate SQL: Deteksi Pelanggan yang Kabur Sejak Dini
Studi kasus toko_berkah: 1.240 pelanggan hilang dalam setahun, dan sinyalnya udah kelihatan 2 bulan sebelumnya. Ini query yang bikin kamu nangkap mereka lebih awal.
YoY Growth SQL: Bandingkan Performa dengan Tahun Lalu
Hitung YoY growth di SQL pakai LAG atau self-join, lengkap dengan cara ngindarin pembagi nol dan jebakan bulan yang bolong. Contohnya pakai data toko_berkah.
MoM Growth SQL: Hitung Pertumbuhan Bulanan Otomatis
Berhenti copy-paste omzet bulan lalu ke Excel buat ngitung growth. Satu query SQL pakai LAG bisa ngasih pertumbuhan bulanan otomatis, lengkap sampai bulan yang datanya kosong.