Разве использование NULL в PostgreSQL все еще не использует растровое изображение NULL в заголовке?

Очевидно, PostgreSQL хранит пару значений в заголовке каждой строки базы данных.

Если я не использую значения NULL в этой таблице - пустое растровое изображение все еще там?
Определяет столбцы с NOT NULL есть какая-то разница?

2 ответа

Решение

Это на самом деле сложнее, чем это.

Нулевое растровое изображение требует один бит на столбец в строке, округленный до полных байтов. Он существует только в том случае, если фактическая строка содержит хотя бы одно значение NULL и полностью выделена в этом случае. NOT NULL ограничения напрямую не влияют на это. (Конечно, если все поля вашей таблицы NOT NULL, никогда не может быть нулевого растрового изображения.)

"Заголовок кортежа кучи" (на строку) имеет длину 23 байта. Фактические данные начинаются с кратного MAXALIGN после этого, как правило, 8 байтов в 64-битной ОС (4 байта в 32-битной ОС). Запустите следующую команду из вашего двоичного каталога PostgreSQL от имени пользователя root, чтобы получить окончательный ответ:

./pg_controldata /path/to/my/dbcluster

На типичной установке Debian Postgres 9.3 это будет:

sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main

В любом случае между заголовком и выровненным началом данных есть один свободный байт, который может использовать нулевое растровое изображение. До тех пор, пока ваша таблица имеет 8 столбцов или меньше, NULL-хранилище фактически абсолютно свободно (в отношении дискового пространства).

После этого еще один MAXALIGN (обычно 8 байтов) выделяется для нулевого растрового изображения (плюс заполнение), чтобы покрыть другие (обычно) 64 поля. И т.п.

Это действительно как минимум для версий 8.4 - 9.6 и, скорее всего, не изменится.

Нулевое растровое изображение присутствует, только если в t_infomask установлен бит HEAP_HASNULL. Если он присутствует, он начинается сразу после фиксированного заголовка и занимает достаточно байтов, чтобы иметь один бит на столбец данных (то есть всего битов t_natts). В этом списке битов 1 бит указывает на ненулевое значение, 0 бит является нулевым. Если растровое изображение отсутствует, предполагается, что все столбцы не равны NULL.

http://www.postgresql.org/docs/9.0/static/storage-page-layout.html

поэтому для каждых 8 столбцов вы используете один байт дополнительного хранилища. Затем на каждые около миллиона строк, которые занимают один мегабайт памяти. Не кажется, что это важно. Я бы определил таблицы, как они должны быть определены, и не беспокоиться о нулевых заголовках.

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