Non sorprende che il manuale sia giusto. Ma c'è di più.
Per uno, le dimensioni su disco (in qualsiasi tabella , anche quando non sono effettivamente archiviate su disco) possono essere diverse dalle dimensioni in memoria . Sul disco, l'overhead per varchar
valori brevi fino a 126 byte è ridotto a 1 byte, come indicato nel manuale. Ma l'overhead in memoria è sempre di 4 byte (una volta estratti i singoli valori).
Lo stesso vale per il text
, varchar
, varchar(n)
ochar(n)
- se non che char(n)
è vuota imbottite di n
caratteri e che normalmente non si desidera utilizzarlo. La sua dimensione effettiva può ancora variare nelle codifiche multi-byte perché n
indica un massimo di caratteri, non byte:
stringhe fino a n
caratteri (non byte) di lunghezza.
Tutti usano varlena
internamente.
"char"
(con virgolette doppie) è una creatura diversa e occupa sempre un singolo byte.
I letterali stringa non tipizzati ( 'foo'
) hanno un overhead a byte singolo. Da non confondere con i valori digitati!
Prova 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
Come potete vedere:
- La stringa di 3 byte 'pippo' occupa 4 byte sul disco e 7 byte nella RAM (quindi 1 byte contro 4 byte di sovraccarico).
- La stringa di 140 byte '123 ...' occupa 144 byte sia sul disco che nella RAM (quindi sempre 4 byte di overhead).
- Lo stoccaggio di
integer
non ha costi generali (ma ha requisiti di allineamento che possono imporre imbottitura).
- La riga ha un sovraccarico aggiuntivo di 24 byte per l'intestazione della tupla (più altri 4 byte per tupla per il puntatore dell'elemento nell'intestazione della pagina).
- E, ultimo ma non meno importante: l'overhead del piccolo
varchar
è ancora solo 1 byte mentre non è stato estratto dalla riga, come si può vedere dalle dimensioni della riga. (Ecco perché a volte è più veloce selezionare intere righe.)
Relazionato: