Es überrascht nicht, dass das Handbuch richtig ist. Aber es steckt noch mehr dahinter.
Zum einen kann sich die Größe auf der Festplatte (in jeder Tabelle , auch wenn sie nicht tatsächlich auf der Festplatte gespeichert ist) von der Größe im Speicher unterscheiden . Auf der Festplatte varchar
reduziert sich der Overhead für Kurzwerte bis zu 126 Byte auf 1 Byte, wie im Handbuch angegeben. Der Overhead im Speicher beträgt jedoch immer 4 Byte (sobald einzelne Werte extrahiert wurden).
Das gleiche gilt für text
, varchar
, varchar(n)
oderchar(n)
- außer , dass char(n)
zu Leerzeichen aufgefüllt ist n
Zeichen und Sie in der Regel nicht wollen , es zu benutzen. Die effektive Größe kann bei Multibyte-Codierungen noch variieren, da n
maximal Zeichen und nicht Bytes angegeben werden:
Zeichenfolgen mit einer n
Länge von bis zu Zeichen (nicht Bytes).
Alle von ihnen verwenden varlena
intern.
"char"
(mit doppelten Anführungszeichen) ist eine andere Kreatur und belegt immer ein einzelnes Byte.
Untypisierte String-Literale ( 'foo'
) haben einen Einzelbyte- Overhead. Nicht zu verwechseln mit eingegebenen Werten!
Testen Sie mit 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
Wie du sehen kannst:
- Die 3-Byte-Zeichenfolge 'foo' belegt 4 Byte auf der Festplatte und 7 Byte im RAM (also 1 Byte im Vergleich zu 4 Byte Overhead).
- Die 140-Byte-Zeichenfolge '123 ...' belegt 144 Byte sowohl auf der Festplatte als auch im RAM (also immer 4 Byte Overhead).
- Die Speicherung von
integer
hat keinen Overhead (aber Ausrichtungsanforderungen, die eine Polsterung erfordern können).
- Die Zeile hat einen zusätzlichen Overhead von 24 Byte für den Tupelheader (plus zusätzliche 4 Byte pro Tupel für den Elementzeiger im Seitenkopf).
- Und last but not least: Der Overhead des Small
varchar
beträgt immer noch nur 1 Byte, solange er nicht aus der Zeile extrahiert wurde - wie aus der Zeilengröße hervorgeht. (Deshalb ist es manchmal etwas schneller, ganze Zeilen auszuwählen.)
Verbunden: