Panduan optimasi performa database, estimasi volume data, strategi indexing, dan sistem arsip otomatis untuk menjaga kecepatan akses data Hospital (SIMRS).
Estimasi jumlah record per tahun berdasarkan kapasitas rumah sakit (100-500 pasien/hari).
| Tabel | Volume/Tahun | Keterangan |
|---|---|---|
hms_encounters | 36.000 - 180.000 | Kunjungan pasien (rawat jalan + rawat inap) |
hms_prescription_items | 110.000 - 550.000 | Item resep obat (~3 item per kunjungan) |
hms_bill_items | 73.000 - 365.000 | Item tagihan (~2 item per kunjungan) |
hms_progress_notes | 73.000 - 365.000 | Catatan perkembangan pasien (SOAP) |
hms_appointments | 36.000 - 180.000 | Janji temu / antrian |
hms_payments | 36.000 - 180.000 | Transaksi pembayaran |
hms_doctor_fees | 36.000 - 180.000 | Perhitungan jasa dokter |
hms_prescription_items bisa mencapai 1,5 juta record. Tanpa optimasi, query akan melambat secara signifikan.Composite index ditambahkan pada kolom yang sering digunakan bersamaan dalam query WHERE dan JOIN untuk mempercepat pencarian data.
| Tabel | Index | Kegunaan |
|---|---|---|
hms_encounters | patient + date | Riwayat kunjungan per pasien |
hms_encounters | department + date + status | Daftar kunjungan per departemen |
hms_encounters | doctor + date + status | Jadwal dan daftar pasien dokter |
hms_appointments | date + dept + status | Antrian per departemen hari ini |
hms_appointments | doctor + date | Jadwal appointment dokter |
hms_prescription_items | medicine_code + date | Riwayat penggunaan obat |
hms_prescription_items | prescription + dispensed | Item resep yang belum didispensasi |
hms_bill_items | service + date | Laporan pendapatan per layanan |
hms_bills | patient + status | Tagihan aktif per pasien |
hms_bills | status + date | Laporan tagihan per periode |
hms_bills | paytype + status + date | Laporan per metode pembayaran |
hms_progress_notes | encounter + date | Catatan per kunjungan kronologis |
hms_progress_notes | encounter + role + date | Catatan per profesi (dokter/perawat) |
hms_doctor_fees | doctor + period + status | Rekap jasa dokter per periode |
Partial index hanya mengindex baris yang memenuhi kondisi tertentu. Hasilnya: ukuran index lebih kecil dan query lebih cepat.
| Partial Index | Kondisi | Kegunaan |
|---|---|---|
| Active encounters | WHERE status = 'active' | Hanya index kunjungan yang sedang berlangsung |
| Pending bills | WHERE status = 'pending' | Hanya index tagihan yang belum dibayar |
| Undispensed prescriptions | WHERE dispensed = false | Hanya index resep yang belum didispensasi |
| Pending doctor fees | WHERE status = 'pending' | Hanya index jasa dokter yang belum dibayar |
| Active admissions | WHERE status = 'admitted' | Hanya index pasien rawat inap aktif |
| Today's appointments | WHERE date = CURRENT_DATE | Hanya index janji temu hari ini |
Sistem arsip otomatis memindahkan data lama ke tabel arsip agar tabel utama tetap ringan dan cepat diakses.
Data yang lebih tua dari 24 bulan (default) dipindahkan secara otomatis dari tabel utama ke tabel arsip (*_archive). Tabel utama tetap ringan untuk operasional harian, sementara data lama tetap dapat diakses melalui tabel arsip.
Sistem membuat 7 tabel arsip yang menyimpan data lama dari masing-masing tabel utama.
# Simulasi arsip (tanpa memindahkan data)
php artisan hospital:archive-data --dry-run
# Jalankan arsip dengan default 24 bulan
php artisan hospital:archive-data
# Arsip data lebih tua dari 12 bulan
php artisan hospital:archive-data --months=12
# Arsip hanya tabel tertentu
php artisan hospital:archive-data --table=hms_encounters
--dry-run terlebih dahulu untuk melihat berapa banyak data yang akan dipindahkan sebelum menjalankan arsip sesungguhnya.Jalankan proses arsip secara berkala setiap bulan menggunakan cron job. Contoh: 0 2 1 * * php artisan hospital:archive-data (setiap tanggal 1 jam 02:00).
Setelah proses arsip selesai, perintah VACUUM ANALYZE dijalankan secara otomatis untuk mengoptimalkan storage dan memperbarui statistik query planner PostgreSQL.
Pantau ukuran tabel secara berkala melalui PostgreSQL. Gunakan query pg_total_relation_size() untuk melihat ukuran tabel beserta index-nya.
Untuk tabel dengan lebih dari 1 juta record, pertimbangkan penggunaan table partitioning berdasarkan tanggal (range partitioning) untuk performa query yang lebih optimal.
Daftar 7 tabel arsip yang dibuat oleh sistem untuk menyimpan data lama.
| Tabel Arsip | Tabel Sumber | Data yang Disimpan |
|---|---|---|
hms_encounters_archive | hms_encounters | Kunjungan pasien lama (rawat jalan & rawat inap) |
hms_prescription_items_archive | hms_prescription_items | Item resep obat dari kunjungan lama |
hms_bill_items_archive | hms_bill_items | Item tagihan dari kunjungan lama |
hms_progress_notes_archive | hms_progress_notes | Catatan perkembangan pasien lama (SOAP) |
hms_appointments_archive | hms_appointments | Janji temu dan antrian lama |
hms_payments_archive | hms_payments | Transaksi pembayaran lama |
hms_doctor_fees_archive | hms_doctor_fees | Perhitungan jasa dokter periode lama |