Не дивно, що керівництво правильно. Але в цьому є більше.
Для одного розмір на диску (у будь-якій таблиці , навіть коли він фактично не зберігається на диску) може відрізнятися від розміру в пам'яті . На диску накладні витрати на короткі varchar
значення до 126 байт зменшуються до 1 байта, як зазначено в посібнику. Але накладні витрати в пам’яті завжди становлять 4 байти (після вилучення окремих значень).
Те ж саме відноситься і до text
, varchar
, varchar(n)
абоchar(n)
- за винятком того, що char(n)
воно доповнюється пробілами до n
символів і зазвичай не хочуть , щоб використовувати його. Його ефективний розмір все ще може змінюватись у багатобайтових кодуваннях, оскільки n
позначає максимум символів, а не байтів:
рядки довжиною до n
символів (не байтів).
Всі вони використовують varlena
внутрішньо.
"char"
(з подвійними лапками) - інша істота і завжди займає один байт.
Нетипізовані рядкові літерали ( 'foo'
) мають один байт накладних витрат. Не плутати з набраними значеннями!
Тест с 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
Як ви можете бачити:
- 3-байтовий рядок 'foo' займає 4 байти на диску і 7 байт в оперативній пам’яті (так 1 байт проти 4 байтів накладних витрат).
- 140-байтовий рядок "123 ..." займає 144 байти як на диску, так і в оперативній пам'яті (так завжди 4 байти накладних витрат).
- Зберігання
integer
не має накладних витрат (але воно має вимоги вирівнювання, які можуть накладати прокладки).
- Рядок має додатковий наклад у 24 байти для заголовка кортежу (плюс додаткові 4 байти на кортеж для вказівника елемента в заголовку сторінки).
- І останнє, але не менш важливо: накладні витрати на малий
varchar
досі становлять лише 1 байт, поки він не був витягнутий з рядка - як видно з розміру рядка. (Тому іноді трохи швидше вибирати цілі рядки.)
Пов'язані: