diff --git a/materialized_view_postgresql.MD b/materialized_view_postgresql.MD index 33a7581..d749c15 100644 --- a/materialized_view_postgresql.MD +++ b/materialized_view_postgresql.MD @@ -1,5 +1,3 @@ -Ya, **PostgreSQL memiliki fitur *Materialized View***. - ### Apa itu Materialized View di PostgreSQL? **Materialized View** adalah objek database yang **menyimpan hasil query secara fisik** (seperti tabel), bukan menjalankan ulang query setiap kali dipanggil seperti *VIEW* biasa. @@ -63,15 +61,6 @@ REFRESH MATERIALIZED VIEW CONCURRENTLY laporan_penjualan; * Perlu mekanisme **refresh manual / cron** * Memakai **storage tambahan** ---- - -Kalau mau, saya bisa jelaskan: - -* πŸ” cara auto-refresh pakai **cron / pg_cron** -* ⚑ strategi performa (index materialized view) -* πŸ†š kapan pilih materialized view vs table biasa - -Tinggal bilang mau fokus ke yang mana. Berikut **strategi performa Materialized View di PostgreSQL (fokus INDEX & refresh)** yang sudah terbukti efektif untuk kasus laporan & query berat. @@ -270,10 +259,190 @@ Cari: --- -Kalau mau, saya bisa: +Siap πŸ‘ +Berikut **template INDEX Materialized View PostgreSQL berbasis pola query**. Kamu tinggal **sesuaikan nama kolom & MV**. -* βš™οΈ Buatkan **template index berdasarkan query kamu** -* πŸ“Š Analisis `EXPLAIN ANALYZE` hasilmu -* ⏱️ Rekomendasi jadwal refresh (harian/jam) +--- -Kirim saja **struktur MV + contoh query yang sering dipakai**. +## 🧠 Cara Pakai Template + +1. Ambil **query paling sering dipakai** +2. Cocokkan dengan **pola di bawah** +3. Terapkan index sesuai template + +--- + +## 1️⃣ Query dengan `WHERE =` (Filter Exact) + +```sql +SELECT * +FROM mv_laporan +WHERE tanggal = '2025-12-01' + AND cabang_id = 10; +``` + +### βœ… Index (Composite) + +```sql +CREATE INDEX idx_mv_laporan_tanggal_cabang +ON mv_laporan (tanggal, cabang_id); +``` + +πŸ“Œ **Urutan kolom penting!** +Kolom yang paling sering difilter β†’ di depan. + +--- + +## 2️⃣ Query `WHERE` + `ORDER BY` + +```sql +SELECT * +FROM mv_laporan +WHERE cabang_id = 10 +ORDER BY tanggal DESC +LIMIT 20; +``` + +### βœ… Index + +```sql +CREATE INDEX idx_mv_laporan_cabang_tanggal_desc +ON mv_laporan (cabang_id, tanggal DESC); +``` + +⚑ Menghindari sort mahal. + +--- + +## 3️⃣ Query Range (`BETWEEN`, `>=`, `<=`) + +```sql +SELECT * +FROM mv_laporan +WHERE tanggal BETWEEN '2025-12-01' AND '2025-12-31'; +``` + +### βœ… Index + +```sql +CREATE INDEX idx_mv_laporan_tanggal +ON mv_laporan (tanggal); +``` + +--- + +## 4️⃣ Query JOIN + +```sql +SELECT m.*, c.nama +FROM mv_laporan m +JOIN cabang c ON c.id = m.cabang_id; +``` + +### βœ… Index + +```sql +CREATE INDEX idx_mv_laporan_cabang_id +ON mv_laporan (cabang_id); +``` + +πŸ“Œ Foreign key **WAJIB di-index**. + +--- + +## 5️⃣ Query Dashboard (Data Terbaru) + +```sql +SELECT * +FROM mv_laporan +WHERE tanggal >= CURRENT_DATE - INTERVAL '7 days'; +``` + +### βœ… Partial Index + +```sql +CREATE INDEX idx_mv_laporan_7hari +ON mv_laporan (tanggal) +WHERE tanggal >= CURRENT_DATE - INTERVAL '7 days'; +``` + +πŸš€ Sangat cepat untuk data β€œrecent”. + +--- + +## 6️⃣ Index untuk `REFRESH CONCURRENTLY` + +```sql +REFRESH MATERIALIZED VIEW CONCURRENTLY mv_laporan; +``` + +### βœ… Wajib UNIQUE index + +```sql +CREATE UNIQUE INDEX ux_mv_laporan +ON mv_laporan (tanggal, cabang_id); +``` + +Tanpa ini β†’ ❌ ERROR. + +--- + +## 7️⃣ Index Only Scan (Covering Index) + +```sql +SELECT tanggal, total_penjualan +FROM mv_laporan +WHERE cabang_id = 10; +``` + +### βœ… Index + +```sql +CREATE INDEX idx_mv_laporan_cover +ON mv_laporan (cabang_id) +INCLUDE (tanggal, total_penjualan); +``` + +⚑ Planner bisa **tanpa baca table**. + +--- + +## 8️⃣ Query Aggregasi Ulang (GROUP BY kecil) + +```sql +SELECT cabang_id, SUM(total_penjualan) +FROM mv_laporan +GROUP BY cabang_id; +``` + +### βœ… Index + +```sql +CREATE INDEX idx_mv_laporan_group +ON mv_laporan (cabang_id, total_penjualan); +``` + +--- + +## πŸ”₯ Template Universal (Aman untuk 80% kasus) + +```sql +CREATE UNIQUE INDEX ux_mv_laporan_pk +ON mv_laporan (tanggal, cabang_id); + +CREATE INDEX idx_mv_laporan_filter +ON mv_laporan (cabang_id, tanggal DESC) +INCLUDE (total_penjualan); +``` + +--- + +## βœ… Setelah Buat Index + +Jangan lupa: + +```sql +ANALYZE mv_laporan; +``` + +---