Como era de esperar, el manual es correcto. Pero hay más que eso.
Por un lado, el tamaño en el disco (en cualquier tabla , incluso cuando no está realmente almacenado en el disco) puede ser diferente del tamaño en la memoria . En el disco, la sobrecarga para varchar
valores cortos de hasta 126 bytes se reduce a 1 byte como se indica en el manual. Pero la sobrecarga en la memoria siempre es de 4 bytes (una vez que se extraen los valores individuales).
Lo mismo es cierto para text
, varchar
, varchar(n)
ochar(n)
- excepto que char(n)
es rellenada con blancos a n
los personajes y que normalmente no se desea utilizarlo. Su tamaño efectivo aún puede variar en codificaciones de varios bytes porque n
denota un máximo de caracteres, no bytes:
cadenas de hasta n
caracteres (no bytes) de longitud.
Todos ellos usan varlena
internamente.
"char"
(con comillas dobles) es una criatura diferente y siempre ocupa un solo byte.
Los literales de cadena sin tipo ( 'foo'
) tienen una sobrecarga de un solo byte. ¡No debe confundirse con los valores escritos!
Prueba con pg_column_size()
.
CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
SELECT pg_column_size(id) AS id
, pg_column_size(v_small) AS v_small
, pg_column_size(v_big) AS v_big
, pg_column_size(t) AS t
FROM t
UNION ALL -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
, pg_column_size('foo'::varchar)
, pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
, pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));
id | v_small | v_big | t
----+---------+-------+-----
4 | 4 | 144 | 176
4 | 7 | 144 | 176
Como puedes ver:
- La cadena 'foo' de 3 bytes ocupa 4 bytes en el disco y 7 bytes en la RAM (1 byte frente a 4 bytes de sobrecarga).
- La cadena de 140 bytes '123 ...' ocupa 144 bytes tanto en el disco como en la RAM (siempre 4 bytes de sobrecarga).
- El almacenamiento
integer
no tiene gastos generales (pero tiene requisitos de alineación que pueden imponer relleno).
- La fila tiene una sobrecarga adicional de 24 bytes para el encabezado de la tupla (más 4 bytes adicionales por tupla para el puntero del elemento en el encabezado de la página).
- Y por último, pero no menos importante: la sobrecarga de la pequeña
varchar
sigue siendo de solo 1 byte mientras no se ha extraído de la fila, como se puede ver en el tamaño de la fila. (Es por eso que a veces es un poco más rápido seleccionar filas enteras).
Relacionado: