Размер таблицы с макетом страницы
Я использую PostgreSQL 9.2 на Oracle Linux Server версии 6.3.
Согласно документации макета хранилища, макет страницы содержит:
- PageHeaderData (24 байта)
- n количество точек на элемент (элемент индекса / элемент таблицы) AKA ItemIdData(4 байта)
- свободное место
- п количество предметов
- специальное пространство
Я протестировал его, чтобы составить формулу для оценки ожидаемого размера таблицы...(Концепция TOAST может быть проигнорирована.)
postgres=# \d t1;
Table "public.t1"
Column ',' Type ',' Modifiers
---------------+------------------------+------------------------------
code |character varying(8) |not null
name |character varying(100) |not null
act_yn |character(1) |not null default 'N'::bpchar
desc |character varying(100) |not null
org_code1 |character varying(3) |
org_cole2 |character varying(10) |
postgres=# insert into t1 values(
'11111111', -- 8
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'Y',
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'111',
'1111111111');
postgres=# select * from pgstattuple('t1');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
8192 | 1 | 252 | 3.08 | 1 | 252 | 3.08 | 7644 | 93.31
(1 row)
Почему tuple_len
252 вместо 249? ("222 байта максимальной длины всего столбца" PLUS
"27 байт заголовка кортежа, за которым следует необязательное нулевое растровое изображение, необязательное поле идентификатора объекта и пользовательские данные")
Откуда берутся 3 байта?
Что-то не так с моей формулой?
1 ответ
Ваш расчет отключен в нескольких точках.
- Размер хранилища
varchar
или жеtext
есть (цитируя руководство здесь):
Требование к памяти для короткой строки (до 126 байт) составляет 1 байт плюс фактическая строка, которая включает пробел в случае символа. Более длинные строки имеют 4 байта служебной информации вместо 1. Длинные строки сжимаются системой автоматически, поэтому физические требования к диску могут быть меньше.
Жирный акцент мой, чтобы ответить на вопрос в комментарии.
HeapTupeHeader занимает 23 байта, а не 27 байтов.
1 байт заполнения из-за выравнивания данных (кратно 8), которое в этом случае используется для битовой маски NULL.
Нет заполнения для типа
varchar
,
Итак, фактический расчет:
23 -- heaptupleheader
+ 1 -- NULL bit mask (or padding if all columns are NOT NULL)
+ 8 -- columns
+ 100
+ 1
+ 100
+ 3
+ 10
+ 6 -- 1 byte overhead per varchar column, 6 columns
-> 252 байта.
Я написал пару связанных ответов, вы можете найти большинство из них, связанных с этим (посмотрите на список ссылок справа).