Jawaban singkatnya adalah penyimpanan database lebih dioptimalkan untuk kecepatan daripada ruang.
Misalnya, jika Anda memasukkan 100 baris ke dalam tabel, lalu menghapus setiap baris dengan ID bernomor ganjil, DBMS dapat menulis tabel baru dengan hanya 50 baris, tetapi lebih efisien jika hanya menandai baris yang dihapus sebagai ruang kosong dan gunakan kembali saat Anda memasukkan baris berikutnya. Oleh karena itu tabel memakan ruang dua kali lebih banyak dari yang dibutuhkan saat ini.
Penggunaan "MVCC" oleh Postgres, alih-alih mengunci, untuk manajemen transaksi membuat hal ini lebih mungkin terjadi, karena UPDATE biasanya melibatkan penulisan baris baru ke penyimpanan, lalu menandai baris lama dihapus setelah tidak ada transaksi yang melihatnya.
Dengan membuang dan memulihkan database, Anda membuat ulang DB tanpa semua ruang kosong ini. Ini pada dasarnya adalah apa VACUUM FULL
perintah tidak - itu menulis ulang data saat ini menjadi file baru, lalu menghapus file lama.
Ada ekstensi yang didistribusikan dengan Postgres yang disebut pg_freespace
yang memungkinkan Anda memeriksa beberapa di antaranya. misalnya Anda dapat mencantumkan ukuran tabel utama (tidak termasuk indeks dan kolom yang disimpan dalam tabel "TOAST" terpisah) dan ruang kosong yang digunakan oleh setiap tabel dengan di bawah ini:
Select oid::regclass::varchar as table,
pg_size_pretty(pg_relation_size(oid)/1024 * 1024) As size,
pg_size_pretty(sum(free)) As free
From (
Select c.oid,
(pg_freespace(c.oid)).avail As free
From pg_class c
Join pg_namespace n on n.oid = c.relnamespace
Where c.relkind = 'r'
And n.nspname Not In ('information_schema', 'pg_catalog')
) tbl
Group By oid
Order By pg_relation_size(oid) Desc, sum(free) Desc;