Nic dziwnego, że instrukcja ma rację. Ale jest coś więcej.
Po pierwsze, rozmiar na dysku (w dowolnej tabeli , nawet jeśli faktycznie nie jest przechowywany na dysku) może różnić się od rozmiaru w pamięci . Na dysku narzut dla krótkich varchar
wartości do 126 bajtów jest redukowany do 1 bajtu, jak podano w instrukcji. Ale narzut w pamięci wynosi zawsze 4 bajty (po wyodrębnieniu poszczególnych wartości).
To samo odnosi się do text
, varchar
, varchar(n)
lubchar(n)
- oprócz tego, że char(n)
jest puste, wypełnione do n
znaków i zwykle nie chcą z niego korzystać. Jego efektywny rozmiar może nadal różnić się w kodowaniu wielobajtowym, ponieważ n
oznacza maksymalną liczbę znaków, a nie bajty:
ciągi znaków do długości n
(nie bajtów).
Wszystkie z nich używają varlena
wewnętrznie.
"char"
(z podwójnymi cudzysłowami) jest innym stworzeniem i zawsze zajmuje jeden bajt.
Nieodpisane literały łańcuchowe ( 'foo'
) mają narzut na jeden bajt. Nie należy mylić ich z wpisanymi wartościami!
Przetestuj za pomocą 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
Jak widzisz:
- 3-bajtowy ciąg „foo” zajmuje 4 bajty na dysku i 7 bajtów w pamięci RAM (więc 1 bajt vs. 4 bajty narzutu).
- 140-bajtowy ciąg „123 ...” zajmuje 144 bajty zarówno na dysku, jak i w pamięci RAM (czyli zawsze 4 bajty narzutu).
- Przechowywanie
integer
nie ma narzutu (ale ma wymagania dotyczące wyrównania, które mogą nałożyć wypełnienie).
- Wiersz ma dodatkowy narzut 24 bajtów dla nagłówka krotki (plus dodatkowe 4 bajty na krotkę dla wskaźnika pozycji w nagłówku strony).
- I na koniec: narzut małego
varchar
ma wciąż tylko 1 bajt, podczas gdy nie został wyodrębniony z wiersza - co widać na podstawie wielkości wiersza. (Dlatego czasami zaznaczanie całych wierszy jest nieco szybsze).
Związane z: