Krátká odpověď je, že databázové úložiště je více optimalizováno pro rychlost než prostor.
Pokud jste například do tabulky vložili 100 řádků a poté smazali každý řádek s lichým ID, DBMS by mohl vypsat novou tabulku s pouze 50 řádky, ale je pro něj efektivnější jednoduše označit smazané řádky jako volné místo. a znovu je použít při příštím vložení řádku. Stůl tedy zabírá dvakrát tolik místa, než je aktuálně potřeba.
Použití "MVCC" pro Postgres pro správu transakcí spíše než zamykání to činí ještě pravděpodobnějším, protože AKTUALIZACE obvykle zahrnuje zápis nového řádku do úložiště a poté označení starého řádku za smazaný, jakmile se na něj žádné transakce nedívají.
Vyprázdněním a obnovením databáze znovu vytvoříte DB bez tohoto volného místa. To je v podstatě to, co VACUUM FULL
příkaz dělá - přepíše aktuální data do nového souboru a poté smaže starý soubor.
Existuje rozšíření distribuované s Postgres s názvem pg_freespace
což vám umožní něco z toho prozkoumat. např. můžete uvést velikost hlavní tabulky (bez indexů a sloupců uložených v samostatných tabulkách „TOAST“) a volné místo používané každou tabulkou pomocí následujícího:
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;