Разве использование NULL в PostgreSQL все еще не использует растровое изображение NULL в заголовке? - PullRequest
12 голосов
/ 15 февраля 2011

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

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

Ответы [ 2 ]

24 голосов
/ 12 сентября 2011

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

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

3 голосов
/ 15 февраля 2011

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

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

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

...