sql >> Base de Datos >  >> RDS >> PostgreSQL

Dar sentido a los tamaños de fila de Postgres

El cálculo del tamaño de fila es mucho más complejo que eso.

El almacenamiento normalmente se divide en páginas de datos de 8 kB . Hay una pequeña sobrecarga fija por página, posibles restos que no son lo suficientemente grandes como para caber en otra tupla y, lo que es más importante, filas muertas o un porcentaje inicialmente reservado con el FILLFACTOR ajuste.

Y hay aún más gastos generales por fila (tupla):un identificador de elemento de 4 bytes al comienzo de la página, el HeapTupleHeader de 23 bytes y relleno de alineación . El inicio del encabezado de la tupla, así como el inicio de los datos de la tupla, se alinean en un múltiplo de MAXALIGN , que es de 8 bytes en una máquina típica de 64 bits. Algunos tipos de datos requieren alineación con el siguiente múltiplo de 2, 4 u 8 bytes.

Citando el manual en la tabla del sistema pg_tpye :

typalign es la alineación requerida cuando se almacena un valor de este tipo. Se aplica al almacenamiento en disco, así como a la mayoría de las representaciones del valor dentro de PostgreSQL. Cuando se almacenan varios valores de forma consecutiva, como en la representación de una fila completa en disco, el relleno se inserta antes de un dato de este tipo para que comience en el límite especificado. La referencia de alineación es el comienzo del primer dato de la secuencia.

Los valores posibles son:

  • c =char alineación, es decir, no se necesita alineación.

  • s =short alineación (2 bytes en la mayoría de las máquinas).

  • i =int alineación (4 bytes en la mayoría de las máquinas).

  • d =double alineación (8 bytes en muchas máquinas, pero no en todas).

Lea sobre los conceptos básicos en el manual aquí.

Tu ejemplo

Esto da como resultado 4 bytes de relleno después de sus 3 integer columnas, porque la timestamp la columna requiere double alineación y debe comenzar en el siguiente múltiplo de 8 bytes.

Entonces, una fila ocupa:

   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

Más identificador de elemento por tupla en el encabezado de la página (como lo señala @A.H. en el comentario):

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

Entonces llegamos a los 52 bytes observados. .

El cálculo pg_relation_size(tbl) / count(*) es una estimación pesimista. pg_relation_size(tbl) incluye bloat (filas muertas) y espacio reservado por fillfactor , así como gastos generales por página de datos y por tabla. (Y ni siquiera mencionamos la compresión para largas varlena datos en las tablas TOAST, ya que no se aplica aquí.)

Puede instalar el módulo adicional pgstattuple y llamar a SELECT * FROM pgstattuple('tbl_name'); para obtener más información sobre el tamaño de la tabla y la tupla.

Relacionado:

  • Tamaño de tabla con diseño de página
  • Calcular y ahorrar espacio en PostgreSQL