Размер таблицы с макетом страницы

Я использую 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 байта.

Я написал пару связанных ответов, вы можете найти большинство из них, связанных с этим (посмотрите на список ссылок справа).

Другие вопросы по тегам