Pagi-pagi sekali setiap hari pekerjaan pgAgent menyegarkan isi tabel A dari tabel B pada database PostgreSQL 8.4 saya. Tabel A berisi sekitar 140 ribu catatan di 91 kolom dan memiliki dua indeks - satu sebagai bagian dari PRIMARY KEY dan yang lainnya indeks GIST pada kolom geometri POINT PostGIS.
Untuk membuat proses berjalan sedikit lebih cepat, pekerjaan menjatuhkan indeks pada kolom geometri, sebelum menghapus catatan dalam tabel A dan memasukkan catatan dari tabel B, kemudian indeks dibuat kembali. Ini semua dilakukan daemon autovacuum bekerja ketika terasa seperti itu (setelah sepuluh menit atau lebih dari membandingkan statistik pekerjaan dan statistik tabel untuk waktu penyelesaian pekerjaan dan waktu menjalankan autovacuum).
Setelah memeriksa meja pagi ini setelah semua ini terjadi, statistik tabel mengatakan kepada saya ukuran meja 272MB, ukuran tabel TOAST adalah 8192bytes, dan ukuran indeks 23MB. Ini tampak cukup besar sehingga saya mengeluarkan perintah REINDEX di atas meja dan ukuran indeks turun ke 9832kB.
Pertanyaan saya adalah ini:
Mengapa REINDEX ternyata mengurangi ukuran indeks begitu banyak ketika indeks (atau setidaknya indeks kolom geometri) telah dibuat lagi dari awal? Haruskah saya memastikan bahwa tabel telah disedot / dianalisis sebelum indeks dibangun? Bukankah menjatuhkan indeks pada kunci primer merupakan faktor dalam hal ini? Apa yang saya lewatkan?
sumber
ANALYZE
ukuran yang dilaporkan juga berkurang.Jawaban:
Jika pernyataan CREATE INDEX melihat bahwa sesi lain memegang snapshot aktif yang mungkin masih tertarik pada catatan yang dihapus, maka itu termasuk catatan yang dihapus ke dalam indeks baru.
Demikian pula, jika REINDEX melihat bahwa sesi lain memegang snapshot aktif yang mungkin masih tertarik pada catatan yang dihapus, maka itu termasuk catatan yang dihapus ke dalam indeks baru.
Jika VACUUM melihat bahwa sesi lain memegang snapshot aktif yang mungkin masih tertarik pada catatan yang dihapus, maka itu menyimpan catatan tersebut di dalam tabel. Dan kemudian REINDEX atau CREATE INDEX juga perlu membawanya ke dalam indeks baru, selama snapshot itu masih ada.
Begitu ada atau tidak ada lagi snapshot yang dapat melihat baris yang dihapus, maka VACUUM dapat menghapusnya dari tabel. Tapi CREATE INDEX atau REINDEX juga bisa saja tidak membawa mereka ke dalam indeks baru, apakah VACUUM sudah sempat mengeluarkan mereka dari kemampuan atau tidak.
Jadi dalam skenario Anda, peran VACUUM antara CREATE INDEX awal dan REINDEX mungkin hanya menyita waktu, selama waktu itu transaksi jangka panjang Anda semoga hilang dengan sendirinya dan menjatuhkan snapshot yang mengganggu.
sumber
Setelah mencoba berbagai perintah untuk melakukan sesuatu, tampaknya melakukan VACUUM sebelum instruksi REINDEX adalah satu-satunya cara untuk mendapatkan pengurangan ukuran, mungkin karena ruang tanpa vakum menambah indeks (pengindeksan catatan yang dihapus?). Memaksa tabel menulis ulang dengan menggunakan
melakukan hal yang sama, karena membersihkan ruang yang tidak digunakan.
Harus VACUUM di tengah proses tidak mematahkan aliran sedikit karena orang harus mengeluarkan perintah VACUUM di luar transaksi.
sumber