Разве использование 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 столбцов вы используете один байт дополнительного хранилища. Затем на каждые около миллиона строк, которые занимают один мегабайт памяти. Не кажется, что это важно. Я бы определил таблицы, как они должны быть определены, и не беспокоиться о нулевых заголовках.