Il calcolo della dimensione delle righe è molto più complesso di così.
Lo spazio di archiviazione è in genere partizionato in pagine di dati da 8 kB . C'è un piccolo sovraccarico fisso per pagina, eventuali resti non abbastanza grandi da contenere un'altra tupla e, soprattutto, righe morte o una percentuale inizialmente riservata con FILLFACTOR
impostazione.
E c'è ancora più sovraccarico per riga (tupla):un identificatore di elemento di 4 byte all'inizio della pagina, l'HeapTupleHeader
di 23 byte e padding di allineamento . L'inizio dell'intestazione della tupla e l'inizio dei dati della tupla sono allineati a un multiplo di MAXALIGN
, che è di 8 byte su una tipica macchina a 64 bit. Alcuni tipi di dati richiedono l'allineamento al multiplo successivo di 2, 4 o 8 byte.
Citando il manuale sulla tabella di sistema pg_tpye
:
typalign
è l'allineamento richiesto quando si memorizza un valore di questo tipo. Si applica all'archiviazione su disco così come alla maggior parte delle rappresentazioni del valore all'interno di PostgreSQL. Quando più valori vengono memorizzati consecutivamente, come nella rappresentazione di una riga completa su disco, il riempimento viene inserito prima di un dato di questo tipo in modo che inizi sul limite specificato. Il riferimento di allineamento è l'inizio del primo dato nella sequenza.
I valori possibili sono:
-
c
=char
allineamento, ovvero non è necessario alcun allineamento. -
s
=short
allineamento (2 byte sulla maggior parte delle macchine). -
i
=int
allineamento (4 byte sulla maggior parte delle macchine). -
d
=double
allineamento (8 byte su molte macchine, ma non tutte).
Leggi le nozioni di base nel manuale qui.
Il tuo esempio
Ciò si traduce in 4 byte di riempimento dopo il tuo 3 integer
colonne, perché il timestamp
la colonna richiede double
allineamento e deve iniziare dal multiplo successivo di 8 byte.
Quindi, una riga occupa:
23 -- heaptupleheader
+ 1 -- padding or NULL bitmap
+ 12 -- 3 * integer (no alignment padding here)
+ 4 -- padding after 3rd integer
+ 8 -- timestamp
+ 0 -- no padding since tuple ends at multiple of MAXALIGN
Più l'identificatore dell'elemento per tupla nell'intestazione della pagina (come sottolineato da @A.H. nel commento):
+ 4 -- item identifier in page header
------
= 52 bytes
Quindi arriviamo ai 52 byte osservati .
Il calcolo pg_relation_size(tbl) / count(*)
è una stima pessimistica. pg_relation_size(tbl)
include bloat (righe morte) e spazio riservato da fillfactor
, nonché le spese generali per pagina di dati e per tabella. (E non abbiamo nemmeno menzionato la compressione per varlena
long dati nelle tabelle TOAST, poiché non si applica qui.)
Puoi installare il modulo aggiuntivo pgstattuple e chiamare SELECT * FROM pgstattuple('tbl_name');
per ulteriori informazioni sulla dimensione della tabella e della tupla.
Correlati:
- Dimensioni tabella con layout di pagina
- Calcolo e risparmio di spazio in PostgreSQL