Sem surpresa, o manual está certo. Mas há mais do que isso.
Por um lado, o tamanho do disco (em qualquer tabela , mesmo quando não está realmente armazenado no disco) pode ser diferente do tamanho da memória . No disco, a sobrecarga para varchar
valores curtos de até 126 bytes é reduzida para 1 byte, conforme indicado no manual. Mas a sobrecarga na memória é sempre de 4 bytes (depois que os valores individuais são extraídos).
O mesmo é verdadeiro para text
, varchar
, varchar(n)
ouchar(n)
- exceto que char(n)
é de preenchimento em branco para n
caracteres e você normalmente não quer usá-lo. Seu tamanho efetivo ainda pode variar nas codificações de vários bytes, porque n
indica um máximo de caracteres, não bytes:
seqüências de n
caracteres até caracteres (não bytes) de comprimento.
Todos eles usam varlena
internamente.
"char"
(com aspas duplas) é uma criatura diferente e ocupa sempre um único byte.
Os literais de seqüência de caracteres sem tipo ( 'foo'
) têm uma única sobrecarga de bytes. Não deve ser confundido com valores digitados!
Teste com 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 você pode ver:
- A string de 3 bytes 'foo' ocupa 4 bytes no disco e 7 bytes na RAM (portanto, 1 byte vs. 4 bytes de sobrecarga).
- A cadeia de caracteres de 140 bytes '123 ...' ocupa 144 bytes no disco e na RAM (portanto, sempre 4 bytes de sobrecarga).
- O armazenamento de
integer
não possui sobrecarga (mas possui requisitos de alinhamento que podem impor preenchimento).
- A linha possui uma sobrecarga adicional de 24 bytes para o cabeçalho da tupla (mais 4 bytes adicionais por tupla para o ponteiro do item no cabeçalho da página).
- E por último, mas não menos importante: a sobrecarga do pequeno
varchar
ainda tem apenas 1 byte, enquanto não foi extraída da linha - como pode ser visto no tamanho da linha. É por isso que às vezes é um pouco mais rápido selecionar linhas inteiras.
Palavras-chave: