PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Dare un senso alle dimensioni delle righe di Postgres

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