Krótka odpowiedź brzmi, że przechowywanie bazy danych jest bardziej zoptymalizowane pod kątem szybkości niż miejsca.
Na przykład, jeśli wstawisz 100 wierszy do tabeli, a następnie usuniesz każdy wiersz z nieparzystym identyfikatorem, DBMS może zapisać nową tabelę z tylko 50 wierszami, ale bardziej efektywne jest po prostu oznaczenie usuniętych wierszy jako wolnego miejsca i użyj ich ponownie, gdy następnym razem wstawisz wiersz. Dlatego stół zajmuje dwa razy więcej miejsca niż jest obecnie potrzebne.
Użycie przez Postgres „MVCC” zamiast blokowania, ponieważ zarządzanie transakcjami sprawia, że jest to jeszcze bardziej prawdopodobne, ponieważ UPDATE zwykle polega na zapisaniu nowego wiersza do pamięci, a następnie oznaczeniu starego wiersza jako usuniętego, gdy żadna transakcja go nie przegląda.
Zrzucając i przywracając bazę danych, odtwarzasz bazę danych bez całego wolnego miejsca. To jest zasadniczo to, co VACUUM FULL
polecenie robi - przepisuje bieżące dane do nowego pliku, a następnie usuwa stary plik.
Istnieje rozszerzenie dystrybuowane z Postgresem o nazwie pg_freespace
co pozwoli ci zbadać niektóre z nich. np. możesz podać rozmiar głównej tabeli (bez indeksów i kolumn przechowywanych w osobnych tabelach "TOAST") oraz wolne miejsce używane przez każdą tabelę z poniższym:
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;