PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Donner un sens aux tailles de lignes Postgres

Le calcul de la taille des lignes est beaucoup plus complexe que cela.

Le stockage est généralement partitionné en pages de données de 8 Ko . Il y a un petit surcoût fixe par page, des restes possibles pas assez grands pour tenir un autre tuple, et plus important encore des lignes mortes ou un pourcentage initialement réservé avec le FILLFACTOR réglage.

Et il y a encore plus de surcharge par ligne (tuple) :un identifiant d'élément de 4 octets en début de page, le HeapTupleHeader de 23 octets et remplissage d'alignement . Le début de l'en-tête du tuple ainsi que le début des données du tuple sont alignés sur un multiple de MAXALIGN , soit 8 octets sur une machine 64 bits classique. Certains types de données nécessitent un alignement sur le prochain multiple de 2, 4 ou 8 octets.

Citant le manuel sur la table système pg_tpye :

typalign est l'alignement requis lors du stockage d'une valeur de ce type. Il s'applique au stockage sur disque ainsi qu'à la plupart des représentations de la valeur dans PostgreSQL. Lorsque plusieurs valeurs sont stockées consécutivement, comme dans la représentation d'une ligne complète sur disque, un remplissage est inséré avant une donnée de ce type afin qu'elle commence à la frontière spécifiée. La référence d'alignement est le début de la première donnée de la séquence.

Les valeurs possibles sont :

  • c =char alignement, c'est-à-dire qu'aucun alignement n'est nécessaire.

  • s =short alignement (2 octets sur la plupart des machines).

  • i =int alignement (4 octets sur la plupart des machines).

  • d =double alignement (8 octets sur de nombreuses machines, mais pas toutes).

Découvrez les bases dans le manuel ici.

Votre exemple

Cela se traduit par 4 octets de remplissage après vos 3 int colonnes, car l'timestamp la colonne nécessite double l'alignement et doit commencer au prochain multiple de 8 octets.

Ainsi, une ligne occupe :

   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

Plus l'identifiant d'élément par tuple dans l'en-tête de page (comme indiqué par @A.H. dans le commentaire) :

 +  4   -- item identifier in page header
------
 = 52 bytes

Nous arrivons donc aux 52 octets observés .

Le calcul pg_relation_size(tbl) / count(*) est une estimation pessimiste. pg_relation_size(tbl) inclut les ballonnements (lignes mortes) et l'espace réservé par fillfactor , ainsi que les frais généraux par page de données et par tableau. (Et nous n'avons même pas mentionné la compression pour le long varlena données dans les tables TOAST, car cela ne s'applique pas ici.)

Vous pouvez installer le module supplémentaire pgstattuple et appeler SELECT * FROM pgstattuple('tbl_name'); pour plus d'informations sur la taille des tables et des tuples.

Connexe :

  • Taille du tableau avec mise en page
  • Calculer et économiser de l'espace dans PostgreSQL