Не дивно, що керівництво правильно. Але в цьому є більше.
Для одного розмір на диску (у будь-якій таблиці , навіть коли він фактично не зберігається на диску) може відрізнятися від розміру в пам'яті . На диску накладні витрати на короткі 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 байт, поки він не був витягнутий з рядка - як видно з розміру рядка. (Тому іноді трохи швидше вибирати цілі рядки.)
Пов'язані: